├── .classpath
├── .cvsignore
├── .gitignore
├── .project
├── .settings
├── org.eclipse.core.resources.prefs
├── org.eclipse.jdt.core.prefs
└── org.eclipse.jdt.ui.prefs
├── LICENSE.txt
├── NOTICE.txt
├── build.xml
├── lib
├── ant.jar
├── commons-cli-1.0-LICENSE
├── commons-cli-1.0.jar
└── junit.jar
├── project.properties
├── project.xml
├── readme.txt
├── resources
└── logging.properties
├── src
├── main
│ └── zipdiff
│ │ ├── DifferenceCalculator.java
│ │ ├── Differences.java
│ │ ├── Main.java
│ │ ├── ant
│ │ ├── ZipDiffTask.java
│ │ └── package.html
│ │ ├── output
│ │ ├── AbstractBuilder.java
│ │ ├── Builder.java
│ │ ├── BuilderFactory.java
│ │ ├── HtmlBuilder.java
│ │ ├── TextBuilder.java
│ │ ├── XmlBuilder.java
│ │ ├── ZipBuilder.java
│ │ └── package.html
│ │ ├── package.html
│ │ └── util
│ │ └── StringUtil.java
├── metadata
│ └── JAR-manifest.txt
└── test
│ └── zipdiff
│ └── DifferenceCalculatorTest.java
└── xdocs
├── credits.xml
├── index.xml
├── navigation.xml
├── output.xml
├── related.xml
├── sample-output.html
└── tools.xml
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.cvsignore:
--------------------------------------------------------------------------------
1 | target
2 | maven.log
3 | velocity.log
4 | build
5 | bin
6 | junit-reports
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | target
2 | maven.log
3 | velocity.log
4 | build
5 | bin
6 | junit-reports
7 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | zipdiff
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 |
15 | org.eclipse.jdt.core.javanature
16 |
17 |
18 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.core.resources.prefs:
--------------------------------------------------------------------------------
1 | #Fri Jul 15 10:17:52 CEST 2011
2 | eclipse.preferences.version=1
3 | encoding/=UTF-8
4 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | #Tue Aug 02 14:27:43 CEST 2011
2 | eclipse.preferences.version=1
3 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.5
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12 | org.eclipse.jdt.core.compiler.source=1.5
13 | org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
14 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
15 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
16 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
17 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
18 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
19 | org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
20 | org.eclipse.jdt.core.formatter.alignment_for_assignment=0
21 | org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
22 | org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
23 | org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
24 | org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
25 | org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
26 | org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
27 | org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
28 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
29 | org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
30 | org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
31 | org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
32 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
33 | org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
34 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
35 | org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
36 | org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
37 | org.eclipse.jdt.core.formatter.blank_lines_after_package=1
38 | org.eclipse.jdt.core.formatter.blank_lines_before_field=1
39 | org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
40 | org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
41 | org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
42 | org.eclipse.jdt.core.formatter.blank_lines_before_method=1
43 | org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
44 | org.eclipse.jdt.core.formatter.blank_lines_before_package=0
45 | org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
46 | org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
47 | org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
48 | org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
49 | org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
50 | org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
51 | org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
52 | org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
53 | org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
54 | org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
55 | org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
56 | org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
57 | org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
58 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
59 | org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
60 | org.eclipse.jdt.core.formatter.comment.format_block_comments=false
61 | org.eclipse.jdt.core.formatter.comment.format_header=false
62 | org.eclipse.jdt.core.formatter.comment.format_html=true
63 | org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=false
64 | org.eclipse.jdt.core.formatter.comment.format_line_comments=false
65 | org.eclipse.jdt.core.formatter.comment.format_source_code=true
66 | org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
67 | org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
68 | org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
69 | org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
70 | org.eclipse.jdt.core.formatter.comment.line_length=3000
71 | org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
72 | org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
73 | org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
74 | org.eclipse.jdt.core.formatter.compact_else_if=true
75 | org.eclipse.jdt.core.formatter.continuation_indentation=4
76 | org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=4
77 | org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
78 | org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
79 | org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
80 | org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
81 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
82 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
83 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
84 | org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
85 | org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
86 | org.eclipse.jdt.core.formatter.indent_empty_lines=false
87 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
88 | org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
89 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
90 | org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
91 | org.eclipse.jdt.core.formatter.indentation.size=4
92 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
93 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
94 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_member=insert
95 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
96 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
97 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
98 | org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
99 | org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
100 | org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
101 | org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=insert
102 | org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
103 | org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
104 | org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
105 | org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
106 | org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
107 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
108 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
109 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
110 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
111 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
112 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
113 | org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
114 | org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
115 | org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
116 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
117 | org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
118 | org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
119 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
120 | org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
121 | org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
122 | org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
123 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
124 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
125 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
126 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
127 | org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
128 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
129 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
130 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
131 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
132 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
133 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
134 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
135 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
136 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
137 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
138 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
139 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
140 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
141 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
142 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
143 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
144 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
145 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
146 | org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
147 | org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
148 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
149 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
150 | org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
151 | org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
152 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
153 | org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
154 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
155 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
156 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
157 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
158 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
159 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
160 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
161 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
162 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
163 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
164 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
165 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
166 | org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
167 | org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
168 | org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
169 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
170 | org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
171 | org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
172 | org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
173 | org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
174 | org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
175 | org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
176 | org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
177 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
178 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
179 | org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
180 | org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
181 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
182 | org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
183 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
184 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
185 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
186 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
187 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
188 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
189 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
190 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
191 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
192 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
193 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
194 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
195 | org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
196 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
197 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
198 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
199 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
200 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
201 | org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
202 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
203 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
204 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
205 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
206 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
207 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
208 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
209 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
210 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
211 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
212 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
213 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
214 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
215 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
216 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
217 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
218 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
219 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
220 | org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
221 | org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
222 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
223 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
224 | org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
225 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
226 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
227 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
228 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
229 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
230 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
231 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
232 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
233 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
234 | org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
235 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
236 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
237 | org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
238 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
239 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
240 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
241 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
242 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
243 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
244 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
245 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
246 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
247 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
248 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
249 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
250 | org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
251 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
252 | org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
253 | org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
254 | org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
255 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
256 | org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
257 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
258 | org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
259 | org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
260 | org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
261 | org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
262 | org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
263 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
264 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
265 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
266 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
267 | org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
268 | org.eclipse.jdt.core.formatter.join_lines_in_comments=true
269 | org.eclipse.jdt.core.formatter.join_wrapped_lines=true
270 | org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=true
271 | org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
272 | org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=true
273 | org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=true
274 | org.eclipse.jdt.core.formatter.lineSplit=300
275 | org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
276 | org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
277 | org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
278 | org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=50
279 | org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
280 | org.eclipse.jdt.core.formatter.tabulation.char=tab
281 | org.eclipse.jdt.core.formatter.tabulation.size=4
282 | org.eclipse.jdt.core.formatter.use_on_off_tags=true
283 | org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
284 | org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
285 | org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
286 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.ui.prefs:
--------------------------------------------------------------------------------
1 | #Tue Aug 02 14:21:30 CEST 2011
2 | cleanup.add_default_serial_version_id=false
3 | cleanup.add_generated_serial_version_id=true
4 | cleanup.add_missing_annotations=true
5 | cleanup.add_missing_deprecated_annotations=true
6 | cleanup.add_missing_methods=false
7 | cleanup.add_missing_nls_tags=false
8 | cleanup.add_missing_override_annotations=true
9 | cleanup.add_missing_override_annotations_interface_methods=true
10 | cleanup.add_serial_version_id=true
11 | cleanup.always_use_blocks=true
12 | cleanup.always_use_parentheses_in_expressions=true
13 | cleanup.always_use_this_for_non_static_field_access=false
14 | cleanup.always_use_this_for_non_static_method_access=false
15 | cleanup.convert_to_enhanced_for_loop=false
16 | cleanup.correct_indentation=true
17 | cleanup.format_source_code=true
18 | cleanup.format_source_code_changes_only=false
19 | cleanup.make_local_variable_final=false
20 | cleanup.make_parameters_final=false
21 | cleanup.make_private_fields_final=false
22 | cleanup.make_type_abstract_if_missing_method=false
23 | cleanup.make_variable_declarations_final=false
24 | cleanup.never_use_blocks=false
25 | cleanup.never_use_parentheses_in_expressions=false
26 | cleanup.organize_imports=true
27 | cleanup.qualify_static_field_accesses_with_declaring_class=false
28 | cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
29 | cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
30 | cleanup.qualify_static_member_accesses_with_declaring_class=true
31 | cleanup.qualify_static_method_accesses_with_declaring_class=false
32 | cleanup.remove_private_constructors=false
33 | cleanup.remove_trailing_whitespaces=true
34 | cleanup.remove_trailing_whitespaces_all=true
35 | cleanup.remove_trailing_whitespaces_ignore_empty=false
36 | cleanup.remove_unnecessary_casts=true
37 | cleanup.remove_unnecessary_nls_tags=true
38 | cleanup.remove_unused_imports=true
39 | cleanup.remove_unused_local_variables=false
40 | cleanup.remove_unused_private_fields=true
41 | cleanup.remove_unused_private_members=true
42 | cleanup.remove_unused_private_methods=true
43 | cleanup.remove_unused_private_types=true
44 | cleanup.sort_members=false
45 | cleanup.sort_members_all=false
46 | cleanup.use_blocks=true
47 | cleanup.use_blocks_only_for_return_and_throw=false
48 | cleanup.use_parentheses_in_expressions=true
49 | cleanup.use_this_for_non_static_field_access=false
50 | cleanup.use_this_for_non_static_field_access_only_if_necessary=true
51 | cleanup.use_this_for_non_static_method_access=false
52 | cleanup.use_this_for_non_static_method_access_only_if_necessary=true
53 | cleanup_profile=_HIS
54 | cleanup_settings_version=2
55 | eclipse.preferences.version=1
56 | formatter_profile=_zipdiff
57 | formatter_settings_version=12
58 | org.eclipse.jdt.ui.ignorelowercasenames=true
59 | org.eclipse.jdt.ui.importorder=java;javax;org;com;
60 | org.eclipse.jdt.ui.ondemandthreshold=99
61 | org.eclipse.jdt.ui.staticondemandthreshold=99
62 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 |
2 | zipdiff is available under the terms of the
3 | Apache License, version 2.0
4 |
5 | Link: http://www.apache.org/licenses/
6 |
--------------------------------------------------------------------------------
/NOTICE.txt:
--------------------------------------------------------------------------------
1 | This product includes software developed by the
2 | Apache Software Foundation (http://www.apache.org/).
3 |
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
58 |
59 |
60 |
61 |
62 |
63 |
66 |
68 |
69 |
70 |
71 |
72 |
77 |
78 |
79 |
80 |
81 |
82 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
--------------------------------------------------------------------------------
/lib/ant.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhnb/zipdiff/a113cc4bbe63d8a7ef29cfa74aa06a7128265ec8/lib/ant.jar
--------------------------------------------------------------------------------
/lib/commons-cli-1.0-LICENSE:
--------------------------------------------------------------------------------
1 | /*
2 | * $Header: /home/cvs/jakarta-commons/LICENSE,v 1.4 2002/04/11 13:24:02 dion Exp $
3 | * $Revision: 1.4 $
4 | * $Date: 2002/04/11 13:24:02 $
5 | *
6 | * ====================================================================
7 | *
8 | * The Apache Software License, Version 1.1
9 | *
10 | * Copyright (c) 1999-2001 The Apache Software Foundation. All rights
11 | * reserved.
12 | *
13 | * Redistribution and use in source and binary forms, with or without
14 | * modification, are permitted provided that the following conditions
15 | * are met:
16 | *
17 | * 1. Redistributions of source code must retain the above copyright
18 | * notice, this list of conditions and the following disclaimer.
19 | *
20 | * 2. Redistributions in binary form must reproduce the above copyright
21 | * notice, this list of conditions and the following disclaimer in
22 | * the documentation and/or other materials provided with the
23 | * distribution.
24 | *
25 | * 3. The end-user documentation included with the redistribution, if
26 | * any, must include the following acknowlegement:
27 | * "This product includes software developed by the
28 | * Apache Software Foundation (http://www.apache.org/)."
29 | * Alternately, this acknowlegement may appear in the software itself,
30 | * if and wherever such third-party acknowlegements normally appear.
31 | *
32 | * 4. The names "The Jakarta Project", "Commons", and "Apache Software
33 | * Foundation" must not be used to endorse or promote products derived
34 | * from this software without prior written permission. For written
35 | * permission, please contact apache@apache.org.
36 | *
37 | * 5. Products derived from this software may not be called "Apache"
38 | * nor may "Apache" appear in their names without prior written
39 | * permission of the Apache Group.
40 | *
41 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
42 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
43 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
44 | * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
45 | * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
46 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
47 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
48 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
49 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
51 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
52 | * SUCH DAMAGE.
53 | * ====================================================================
54 | *
55 | * This software consists of voluntary contributions made by many
56 | * individuals on behalf of the Apache Software Foundation. For more
57 | * information on the Apache Software Foundation, please see
58 | * .
59 | *
60 | */
61 |
--------------------------------------------------------------------------------
/lib/commons-cli-1.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhnb/zipdiff/a113cc4bbe63d8a7ef29cfa74aa06a7128265ec8/lib/commons-cli-1.0.jar
--------------------------------------------------------------------------------
/lib/junit.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nhnb/zipdiff/a113cc4bbe63d8a7ef29cfa74aa06a7128265ec8/lib/junit.jar
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | #
2 | # $Header: /cvsroot/zipdiff/zipdiff/project.properties,v 1.1 2004/04/12 19:24:15 sullis Exp $
3 | #
4 | #
5 | #
6 | maven.username=sullis
7 | # ------------------------------------------------------------------------
8 | # M A V E N J A R O V E R R I D E
9 | # ------------------------------------------------------------------------
10 | maven.jar.override=on
11 |
12 | # ------------------------------------------------------------------------
13 | # Jars set explicity by path.
14 | # ------------------------------------------------------------------------
15 | maven.jar.j2ee=/j2sdkee1.3.1/lib/j2ee.jar
16 | maven.jar.javamail=/javamail-1.3.1/lib/mailapi.jar
17 |
18 | #
19 | #
20 | # If "maven.javadoc.private=true", the javadocs will include
21 | # all classes and all methods
22 | #
23 | #
24 | maven.javadoc.private=false
25 |
--------------------------------------------------------------------------------
/project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | 3
11 | zipdiff
12 | zipdiff
13 | 0.4
14 |
15 | zipdiff.sourceforge.net
16 | http://zipdiff.sourceforge.net/
17 |
18 | 2004
19 | zipdiff
20 |
21 | zipdiff
22 |
23 |
24 | zipdiff
25 |
26 |
27 | http://zipdiff.sourceforge.net/
28 |
29 | http://sourceforge.net/tracker/?group_id=106727
30 |
31 | shell.sourceforge.net
32 | /home/groups/z/zi/zipdiff/htdocs
33 | /home/groups/z/zi/zipdiff/htdocs/download
34 |
35 |
36 | scm:cvs:pserver:anonymous@cvs.sourceforge.net:/cvsroot/zipdiff:zipdiff
37 | http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/zipdiff/
38 |
39 |
40 |
41 |
42 | zipdiff user list
43 | http://lists.sourceforge.net/lists/listinfo/zipdiff-users
44 | http://lists.sourceforge.net/lists/listinfo/zipdiff-users
45 | http://sourceforge.net/mailarchive/forum.php?forum=zipdiff-users
46 |
47 |
48 | zipdiff CVS list
49 | http://lists.sourceforge.net/lists/listinfo/zipdiff-cvs
50 | http://lists.sourceforge.net/lists/listinfo/zipdiff-cvs
51 | http://sourceforge.net/mailarchive/forum.php?forum=zipdiff-cvs
52 |
53 |
54 |
55 |
56 |
57 | Sean C. Sullivan
58 | sullis
59 | sean --*-- seansullivan --*-- com
60 |
61 |
62 |
63 | James Stewart
64 | jemsquash1
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | ant
73 | ant
74 | 1.6
75 | http://ant.apache.org/
76 |
77 |
78 | commons-cli
79 | commons-cli
80 | 1.0
81 | http://jakarta.apache.org/commons/cli/
82 |
83 |
84 |
85 |
86 | zipdiff
87 | ${basedir}/src/main
88 |
89 |
90 |
91 | maven-javadoc-plugin
92 | maven-jxr-plugin
93 | maven-changes-plugin
94 | maven-changelog-plugin
95 | maven-checkstyle-plugin
96 | maven-jdepend-plugin
97 | maven-pmd-plugin
98 | maven-developer-activity-plugin
99 | maven-file-activity-plugin
100 | maven-junit-report-plugin
101 | maven-license-plugin
102 | maven-simian-plugin
103 | maven-tasklist-plugin
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | ZipDiff compares two .zip (.jar, .war, .jar) files and creates a list of differences. Plain text, .xml, .html and even a .zip file are supported as output formats.
2 |
3 | ZipDiff can be executed as command line tool or ant task.
4 |
5 |
6 | Command line arguments
7 | ----------------------
8 |
9 | java -jar zipdiff.jar -file1 foo.zip -file2 bar.zip [ options]
10 |
11 | Valid options are:
12 |
13 | --comparecrcvalues compares the crc values instead of the file content
14 | --comparetimestamps compares timestamps instead of file content
15 | --ignorecvsfiles ignores differences in CVS folders
16 | --outputfile name of the output file
17 | --skipoutputprefixes n number of path segment to skip in the output file
18 | --skipprefixes1 n number of path segment to skip in the first file
19 | --skipprefixes2 n number of path segment to skip in the second file
20 | --exitwitherrorondifference use an error code other than 0, if differences have been detected
21 | --verbose print detail messages
22 |
23 |
24 |
25 | This version can be found at https://github.com/nhnb/zipdiff
26 |
27 |
28 | The original zipdiff project was developed by Sean C. Sullivan and James Stewart at http://zipdiff.sourceforge.net/
29 |
30 | License: see LICENSE.txt
31 |
--------------------------------------------------------------------------------
/resources/logging.properties:
--------------------------------------------------------------------------------
1 | # run with -Djava.util.logging.config.file=resources/logging.properties
2 |
3 | handlers= java.util.logging.ConsoleHandler
4 |
5 | .level = FINEST
6 |
7 | java.util.logging.ConsoleHandler.level=FINEST
8 |
9 | java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
10 |
11 | zipdiff.DifferenceCalculator.level=FINER
12 |
13 |
--------------------------------------------------------------------------------
/src/main/zipdiff/DifferenceCalculator.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff;
7 |
8 | import java.io.File;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.util.Enumeration;
12 | import java.util.HashMap;
13 | import java.util.HashSet;
14 | import java.util.Iterator;
15 | import java.util.Map;
16 | import java.util.Set;
17 | import java.util.logging.Level;
18 | import java.util.logging.Logger;
19 | import java.util.regex.Matcher;
20 | import java.util.regex.Pattern;
21 | import java.util.zip.ZipEntry;
22 | import java.util.zip.ZipFile;
23 | import java.util.zip.ZipInputStream;
24 |
25 | import zipdiff.util.StringUtil;
26 |
27 | /**
28 | * Checks and compiles differences between two zip files.
29 | * It also has the ability to exclude entries from the comparison
30 | * based on a regular expression.
31 | *
32 | * @author Sean C. Sullivan, Hendrik Brummermann
33 | */
34 | public class DifferenceCalculator {
35 |
36 | private final Logger logger = Logger.getLogger(getClass().getName());
37 |
38 | private final ZipFile file1;
39 |
40 | private final ZipFile file2;
41 |
42 | private int numberOfPrefixesToSkip1 = 0;
43 |
44 | private int numberOfPrefixesToSkip2 = 0;
45 |
46 | private boolean ignoreTimestamps = false;
47 |
48 | private boolean ignoreCVSFiles = false;
49 |
50 | private boolean compareCRCValues = true;
51 |
52 | private Pattern filesToIgnorePattern;
53 |
54 | private boolean bVerbose = false;
55 |
56 | protected void debug(Object msg) {
57 | if (isVerboseEnabled()) {
58 | System.out.println("[" + DifferenceCalculator.class.getName() + "] " + String.valueOf(msg));
59 | }
60 | }
61 |
62 | /**
63 | * Set the verboseness of the debug output.
64 | * @param b true to make verbose
65 | */
66 | public void setVerbose(boolean b) {
67 | bVerbose = b;
68 | }
69 |
70 | protected boolean isVerboseEnabled() {
71 | return bVerbose;
72 | }
73 |
74 | /**
75 | * Constructor taking 2 filenames to compare
76 | * @throws java.io.IOException
77 | */
78 | public DifferenceCalculator(String filename1, String filename2) throws java.io.IOException {
79 | this(new File(filename1), new File(filename2));
80 | }
81 |
82 | /**
83 | * Constructor taking 2 Files to compare
84 | * @throws java.io.IOException
85 | */
86 | public DifferenceCalculator(File f1, File f2) throws java.io.IOException {
87 | this(new ZipFile(f1), new ZipFile(f2));
88 | }
89 |
90 | /**
91 | * Constructor taking 2 ZipFiles to compare
92 | */
93 | public DifferenceCalculator(ZipFile zf1, ZipFile zf2) {
94 | file1 = zf1;
95 | file2 = zf2;
96 | }
97 |
98 | /**
99 | *
100 | * @param Set A set of regular expressions that when matched against a ZipEntry
101 | * then that ZipEntry will be ignored from the comparison.
102 | * @see java.util.regex
103 | */
104 | public void setFilenameRegexToIgnore(Set patterns) {
105 | if (patterns == null) {
106 | filesToIgnorePattern = null;
107 | } else if (patterns.isEmpty()) {
108 | filesToIgnorePattern = null;
109 | } else {
110 | String regex = "";
111 |
112 | Iterator iter = patterns.iterator();
113 | while (iter.hasNext()) {
114 | String pattern = (String) iter.next();
115 | if (regex.length() > 0) {
116 | regex += "|";
117 | }
118 | regex += "(" + pattern + ")";
119 | }
120 | filesToIgnorePattern = Pattern.compile(regex);
121 | logger.log(Level.FINE, "Regular expression is : " + regex);
122 | }
123 | }
124 |
125 | /**
126 | * returns true if fileToIgnorePattern matches the filename given.
127 | * @param filepath
128 | * @param filename The name of the file to check to see if it should be ignored.
129 | * @return true if the file should be ignored.
130 | */
131 | protected boolean ignoreThisFile(String filepath, String entryName) {
132 | if (entryName == null) {
133 | return false;
134 | } else if (isCVSFile(filepath, entryName) && (ignoreCVSFiles())) {
135 | return true;
136 | } else if (filesToIgnorePattern == null) {
137 | return false;
138 | } else {
139 | Matcher m = filesToIgnorePattern.matcher(entryName);
140 | boolean match = m.matches();
141 | if (match) {
142 | logger.log(Level.FINEST, "Found a match against : " + entryName + " so excluding");
143 | }
144 | return match;
145 | }
146 | }
147 |
148 | protected boolean isCVSFile(String filepath, String entryName) {
149 | if (entryName == null) {
150 | return false;
151 | } else if ((filepath.indexOf("CVS/") != -1) || (entryName.indexOf("CVS/") != -1)) {
152 | return true;
153 | } else {
154 | return false;
155 | }
156 | }
157 |
158 | /**
159 | * Ensure that the comparison checks against the CRCs of the entries.
160 | * @param b true ensures that CRCs will be checked
161 | */
162 | public void setCompareCRCValues(boolean b) {
163 | compareCRCValues = b;
164 | }
165 |
166 | /**
167 | * @return true if this instance will check the CRCs of each ZipEntry
168 | */
169 | public boolean getCompareCRCValues() {
170 | return compareCRCValues;
171 | }
172 |
173 | /**
174 | * sets the number of directory prefixes to skip in the first file
175 | *
176 | * @param numberOfPrefixesToSkip1 number of directory prefixes to skip
177 | */
178 | public void setNumberOfPrefixesToSkip1(int numberOfPrefixesToSkip1) {
179 | this.numberOfPrefixesToSkip1 = numberOfPrefixesToSkip1;
180 | }
181 |
182 | /**
183 | * @return number of directory prefixes to skip
184 | */
185 | public int getNumberOfPrefixesToSkip1() {
186 | return numberOfPrefixesToSkip1;
187 | }
188 |
189 | /**
190 | * sets the number of directory prefixes to skip in the first file
191 | *
192 | * @param numberOfPrefixesToSkip2 number of directory prefixes to skip
193 | */
194 | public void setNumberOfPrefixesToSkip2(int numberOfPrefixesToSkip2) {
195 | this.numberOfPrefixesToSkip2 = numberOfPrefixesToSkip2;
196 | }
197 |
198 | /**
199 | * @return number of directory prefixes to skip
200 | */
201 | public int getNumberOfPrefixesToSkip2() {
202 | return numberOfPrefixesToSkip2;
203 | }
204 |
205 |
206 | /**
207 | * Opens the ZipFile and builds up a map of all the entries. The key is the name of
208 | * the entry and the value is the ZipEntry itself.
209 | * @param zf The ZipFile for which to build up the map of ZipEntries
210 | * @return The map containing all the ZipEntries. The key being the name of the ZipEntry.
211 | * @throws java.io.IOException
212 | * @Deprecated
213 | */
214 | protected Map buildZipEntryMap(ZipFile zf) throws java.io.IOException {
215 | return buildZipEntryMap(zf, 0);
216 | }
217 |
218 | /**
219 | * Opens the ZipFile and builds up a map of all the entries. The key is the name of
220 | * the entry and the value is the ZipEntry itself.
221 | * @param zf The ZipFile for which to build up the map of ZipEntries
222 | * @param number of directory prefixes to skip
223 | * @return The map containing all the ZipEntries. The key being the name of the ZipEntry.
224 | * @throws java.io.IOException
225 | */
226 | protected Map buildZipEntryMap(ZipFile zf, int p) throws java.io.IOException {
227 | Map zipEntryMap = new HashMap();
228 | try {
229 | Enumeration entries = zf.entries();
230 | while (entries.hasMoreElements()) {
231 | ZipEntry entry = (ZipEntry) entries.nextElement();
232 | InputStream is = null;
233 | try {
234 | is = zf.getInputStream(entry);
235 | processZipEntry("", entry, is, zipEntryMap, p);
236 | } finally {
237 | if (is != null) {
238 | is.close();
239 | }
240 | }
241 | }
242 | } finally {
243 | zf.close();
244 | }
245 |
246 | return zipEntryMap;
247 | }
248 |
249 | /**
250 | * Will place ZipEntries for a given ZipEntry into the given Map. More ZipEntries will result
251 | * if zipEntry is itself a ZipFile. All embedded ZipFiles will be processed with their names
252 | * prefixed onto the names of their ZipEntries.
253 | * @param prefix The prefix of the ZipEntry that should be added to the key. Typically used
254 | * when processing embedded ZipFiles. The name of the embedded ZipFile would be the prefix of
255 | * all the embedded ZipEntries.
256 | * @param zipEntry The ZipEntry to place into the Map. If it is a ZipFile then all its ZipEntries
257 | * will also be placed in the Map.
258 | * @param is The InputStream of the corresponding ZipEntry.
259 | * @param zipEntryMap The Map in which to place all the ZipEntries into. The key will
260 | * be the name of the ZipEntry.
261 | * @throws IOException
262 | * @Deprecated
263 | */
264 | protected void processZipEntry(String prefix, ZipEntry zipEntry, InputStream is, Map zipEntryMap) throws IOException {
265 | processZipEntry(prefix, zipEntry, is, zipEntryMap, 0);
266 | }
267 |
268 |
269 | /**
270 | * Will place ZipEntries for a given ZipEntry into the given Map. More ZipEntries will result
271 | * if zipEntry is itself a ZipFile. All embedded ZipFiles will be processed with their names
272 | * prefixed onto the names of their ZipEntries.
273 | * @param prefix The prefix of the ZipEntry that should be added to the key. Typically used
274 | * when processing embedded ZipFiles. The name of the embedded ZipFile would be the prefix of
275 | * all the embedded ZipEntries.
276 | * @param zipEntry The ZipEntry to place into the Map. If it is a ZipFile then all its ZipEntries
277 | * will also be placed in the Map.
278 | * @param is The InputStream of the corresponding ZipEntry.
279 | * @param zipEntryMap The Map in which to place all the ZipEntries into. The key will
280 | * be the name of the ZipEntry.
281 | * @param p number of directory prefixes to skip
282 | * @throws IOException
283 | */
284 | protected void processZipEntry(String prefix, ZipEntry zipEntry, InputStream is, Map zipEntryMap, int p) throws IOException {
285 | if (ignoreThisFile(prefix, zipEntry.getName())) {
286 | logger.log(Level.FINE, "ignoring file: " + zipEntry.getName());
287 | } else {
288 | String name = StringUtil.removeDirectoryPrefix(prefix + zipEntry.getName(), p);
289 | if ((name == null) || name.equals("")) {
290 | return;
291 | }
292 |
293 | logger.log(Level.FINEST, "processing ZipEntry: " + name);
294 | zipEntryMap.put(name, zipEntry);
295 |
296 | if (!zipEntry.isDirectory() && isZipFile(name)) {
297 | processEmbeddedZipFile(name + "!", is, zipEntryMap);
298 | }
299 | }
300 | }
301 |
302 |
303 |
304 | protected void processEmbeddedZipFile(String prefix, InputStream is, Map m) throws java.io.IOException {
305 | ZipInputStream zis = new ZipInputStream(is);
306 |
307 | ZipEntry entry = zis.getNextEntry();
308 |
309 | while (entry != null) {
310 | processZipEntry(prefix, entry, zis, m);
311 | zis.closeEntry();
312 | entry = zis.getNextEntry();
313 | }
314 |
315 | }
316 |
317 | /**
318 | * Returns true if the filename has a valid zip extension.
319 | * i.e. jar, war, ear, zip etc.
320 | * @param filename The name of the file to check.
321 | * @return true if it has a valid extension.
322 | */
323 | public static boolean isZipFile(String filename) {
324 | boolean result;
325 |
326 | if (filename == null) {
327 | result = false;
328 | } else {
329 | String lowercaseName = filename.toLowerCase();
330 | if (lowercaseName.endsWith(".zip")) {
331 | result = true;
332 | } else if (lowercaseName.endsWith(".ear")) {
333 | result = true;
334 | } else if (lowercaseName.endsWith(".war")) {
335 | result = true;
336 | } else if (lowercaseName.endsWith(".rar")) {
337 | result = true;
338 | } else if (lowercaseName.endsWith(".jar")) {
339 | result = true;
340 | } else {
341 | result = false;
342 | }
343 | }
344 |
345 | return result;
346 | }
347 |
348 | /**
349 | * Calculates all the differences between two zip files.
350 | * It builds up the 2 maps of ZipEntries for the two files
351 | * and then compares them.
352 | * @param zf1 The first ZipFile to compare
353 | * @param zf2 The second ZipFile to compare
354 | * @return All the differences between the two files.
355 | * @throws java.io.IOException
356 | * @Deprecated
357 | */
358 | protected Differences calculateDifferences(ZipFile zf1, ZipFile zf2) throws java.io.IOException {
359 | return calculateDifferences(zf1, zf2, 0, 0);
360 | }
361 |
362 | /**
363 | * Calculates all the differences between two zip files.
364 | * It builds up the 2 maps of ZipEntries for the two files
365 | * and then compares them.
366 | * @param zf1 The first ZipFile to compare
367 | * @param zf2 The second ZipFile to compare
368 | * @param p1 number of directory prefixes to skip in the 1st file
369 | * @param p2 number of directory prefixes to skip in the 2nd file
370 | * @return All the differences between the two files.
371 | * @throws java.io.IOException
372 | */
373 | protected Differences calculateDifferences(ZipFile zf1, ZipFile zf2, int p1, int p2) throws java.io.IOException {
374 | Map map1 = buildZipEntryMap(zf1, p1);
375 | Map map2 = buildZipEntryMap(zf2, p2);
376 |
377 | return calculateDifferences(map1, map2);
378 | }
379 |
380 | /**
381 | * Given two Maps of ZipEntries it will generate a Differences of all the
382 | * differences found between the two maps.
383 | * @return All the differences found between the two maps
384 | */
385 | protected Differences calculateDifferences(Map m1, Map m2) {
386 | Differences d = new Differences();
387 |
388 | Set names1 = m1.keySet();
389 | Set names2 = m2.keySet();
390 |
391 | Set allNames = new HashSet();
392 | allNames.addAll(names1);
393 | allNames.addAll(names2);
394 |
395 | Iterator iterAllNames = allNames.iterator();
396 | while (iterAllNames.hasNext()) {
397 | String name = (String) iterAllNames.next();
398 | if (ignoreThisFile("", name)) {
399 | // do nothing
400 | } else if (names1.contains(name) && (!names2.contains(name))) {
401 | d.fileRemoved(name, (ZipEntry) m1.get(name));
402 | } else if (names2.contains(name) && (!names1.contains(name))) {
403 | d.fileAdded(name, (ZipEntry) m2.get(name));
404 | } else if (names1.contains(name) && (names2.contains(name))) {
405 | ZipEntry entry1 = (ZipEntry) m1.get(name);
406 | ZipEntry entry2 = (ZipEntry) m2.get(name);
407 | if (!entriesMatch(entry1, entry2)) {
408 | d.fileChanged(name, entry1, entry2);
409 | }
410 | } else {
411 | throw new IllegalStateException("unexpected state");
412 | }
413 | }
414 |
415 | return d;
416 | }
417 |
418 | /**
419 | * returns true if the two entries are equivalent in type, name, size, compressed size
420 | * and time or CRC.
421 | * @param entry1 The first ZipEntry to compare
422 | * @param entry2 The second ZipEntry to compare
423 | * @return true if the entries are equivalent.
424 | */
425 | protected boolean entriesMatch(ZipEntry entry1, ZipEntry entry2) {
426 | boolean result;
427 |
428 | result = (entry1.isDirectory() == entry2.isDirectory()) && (entry1.getSize() == entry2.getSize()) && (entry1.getCompressedSize() == entry2.getCompressedSize());
429 |
430 | if (!isIgnoringTimestamps()) {
431 | result = result && (entry1.getTime() == entry2.getTime());
432 | }
433 |
434 | if (getCompareCRCValues()) {
435 | result = result && (entry1.getCrc() == entry2.getCrc());
436 | }
437 | return result;
438 | }
439 |
440 | public void setIgnoreTimestamps(boolean b) {
441 | ignoreTimestamps = b;
442 | }
443 |
444 | public boolean isIgnoringTimestamps() {
445 | return ignoreTimestamps;
446 | }
447 |
448 | public boolean ignoreCVSFiles() {
449 | return ignoreCVSFiles;
450 | }
451 |
452 | public void setIgnoreCVSFiles(boolean b) {
453 | ignoreCVSFiles = b;
454 | }
455 |
456 | /**
457 | *
458 | * @return all the differences found between the two zip files.
459 | * @throws java.io.IOException
460 | */
461 | public Differences getDifferences() throws java.io.IOException {
462 | Differences d = calculateDifferences(file1, file2, numberOfPrefixesToSkip1, numberOfPrefixesToSkip2);
463 | d.setFilename1(file1.getName());
464 | d.setFilename2(file2.getName());
465 |
466 | return d;
467 | }
468 | }
469 |
--------------------------------------------------------------------------------
/src/main/zipdiff/Differences.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff;
7 |
8 | import java.util.Iterator;
9 | import java.util.Map;
10 | import java.util.Set;
11 | import java.util.TreeMap;
12 | import java.util.zip.ZipEntry;
13 |
14 | /**
15 | * Used to keep track of difference between 2 zip files.
16 | *
17 | * @author Sean C. Sullivan
18 | */
19 | public class Differences {
20 | private final Map added = new TreeMap();
21 |
22 | private final Map removed = new TreeMap();
23 |
24 | private final Map changed = new TreeMap();
25 |
26 | private final Map ignored = new TreeMap();
27 |
28 | private String filename1;
29 |
30 | private String filename2;
31 |
32 | public Differences() {
33 | // todo
34 | }
35 |
36 | public void setFilename1(String filename) {
37 | filename1 = filename;
38 | }
39 |
40 | public void setFilename2(String filename) {
41 | filename2 = filename;
42 | }
43 |
44 | public String getFilename1() {
45 | return filename1;
46 | }
47 |
48 | public String getFilename2() {
49 | return filename2;
50 | }
51 |
52 | public void fileAdded(String fqn, ZipEntry ze) {
53 | added.put(fqn, ze);
54 | }
55 |
56 | public void fileRemoved(String fqn, ZipEntry ze) {
57 | removed.put(fqn, ze);
58 | }
59 |
60 | public void fileIgnored(String fqn, ZipEntry ze) {
61 | ignored.put(fqn, ze);
62 | }
63 |
64 | public void fileChanged(String fqn, ZipEntry z1, ZipEntry z2) {
65 | ZipEntry[] entries = new ZipEntry[2];
66 | entries[0] = z1;
67 | entries[1] = z2;
68 | changed.put(fqn, entries);
69 | }
70 |
71 | public Map getAdded() {
72 | return added;
73 | }
74 |
75 | public Map getRemoved() {
76 | return removed;
77 | }
78 |
79 | public Map getChanged() {
80 | return changed;
81 | }
82 |
83 | public Map getIgnored() {
84 | return ignored;
85 | }
86 |
87 | public boolean hasDifferences() {
88 | return ((getChanged().size() > 0) || (getAdded().size() > 0) || (getRemoved().size() > 0));
89 | }
90 |
91 | @Override
92 | public String toString() {
93 | StringBuffer sb = new StringBuffer();
94 |
95 | if (added.size() == 1) {
96 | sb.append("1 file was");
97 | } else {
98 | sb.append(added.size() + " files were");
99 | }
100 | sb.append(" added to " + this.getFilename2() + "\n");
101 |
102 | Iterator iter = added.keySet().iterator();
103 | while (iter.hasNext()) {
104 | String name = (String) iter.next();
105 | sb.append("\t[added] " + name + "\n");
106 | }
107 |
108 | if (removed.size() == 1) {
109 | sb.append("1 file was");
110 | } else {
111 | sb.append(removed.size() + " files were");
112 | }
113 | sb.append(" removed from " + this.getFilename2() + "\n");
114 |
115 | iter = removed.keySet().iterator();
116 | while (iter.hasNext()) {
117 | String name = (String) iter.next();
118 | sb.append("\t[removed] " + name + "\n");
119 | }
120 |
121 | if (changed.size() == 1) {
122 | sb.append("1 file changed\n");
123 | } else {
124 | sb.append(changed.size() + " files changed\n");
125 | }
126 |
127 | Set keys = getChanged().keySet();
128 | iter = keys.iterator();
129 | while (iter.hasNext()) {
130 | String name = (String) iter.next();
131 | ZipEntry[] entries = (ZipEntry[]) getChanged().get(name);
132 | sb.append("\t[changed] " + name + " ");
133 | sb.append(" ( size " + entries[0].getSize());
134 | sb.append(" : " + entries[1].getSize());
135 | sb.append(" )\n");
136 | }
137 | int differenceCount = added.size() + changed.size() + removed.size();
138 |
139 | sb.append("Total differences: " + differenceCount);
140 | return sb.toString();
141 | }
142 |
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/zipdiff/Main.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff;
7 |
8 | import java.io.File;
9 | import java.util.HashSet;
10 | import java.util.Set;
11 |
12 | import org.apache.commons.cli.CommandLine;
13 | import org.apache.commons.cli.CommandLineParser;
14 | import org.apache.commons.cli.GnuParser;
15 | import org.apache.commons.cli.HelpFormatter;
16 | import org.apache.commons.cli.Option;
17 | import org.apache.commons.cli.Options;
18 | import org.apache.commons.cli.ParseException;
19 |
20 | import zipdiff.output.Builder;
21 | import zipdiff.output.BuilderFactory;
22 |
23 | /**
24 | * Provides a command line interface to zipdiff
25 | *
26 | * @author Sean C. Sullivan, J.Stewart, Hendrik Brummermann
27 | */
28 | public class Main {
29 | private static final int EXITCODE_ERROR = 2;
30 |
31 | private static final int EXITCODE_DIFF = 1;
32 |
33 | private static final String OPTION_COMPARE_CRC_VALUES = "comparecrcvalues";
34 |
35 | private static final String OPTION_COMPARE_TIMESTAMPS = "comparetimestamps";
36 |
37 | private static final String OPTION_IGNORE_CVS_FILES = "ignorecvsfiles";
38 |
39 | private static final String OPTION_OUTPUT_FILE = "outputfile";
40 |
41 | private static final String OPTION_FILE1 = "file1";
42 |
43 | private static final String OPTION_FILE2 = "file2";
44 |
45 | private static final String OPTION_SKIP_OUTPUT_PREFIXES = "skipoutputprefixes";
46 |
47 | private static final String OPTION_SKIP_PREFIX1 = "skipprefixes1";
48 |
49 | private static final String OPTION_SKIP_PREFIX2 = "skipprefixes2";
50 |
51 | private static final String OPTION_REGEX = "regex";
52 |
53 | private static final String OPTION_EXIT_WITH_ERROR_ON_DIFF = "exitwitherrorondifference";
54 |
55 | private static final String OPTION_VERBOSE = "verbose";
56 |
57 | private static final Options options;
58 |
59 | // static initializer
60 | static {
61 | options = new Options();
62 |
63 | Option compareTS = new Option(OPTION_COMPARE_TIMESTAMPS, OPTION_COMPARE_TIMESTAMPS, false, "Compare timestamps");
64 | compareTS.setRequired(false);
65 |
66 | Option compareCRC = new Option(OPTION_COMPARE_CRC_VALUES, OPTION_COMPARE_CRC_VALUES, false, "Compare CRC values");
67 | compareCRC.setRequired(false);
68 |
69 | Option file1 = new Option(OPTION_FILE1, OPTION_FILE1, true, " first file to compare");
70 | file1.setRequired(true);
71 |
72 | Option file2 = new Option(OPTION_FILE2, OPTION_FILE2, true, " second file to compare");
73 | file2.setRequired(true);
74 |
75 | Option numberOfOutputPrefixesToSkip = new Option(OPTION_SKIP_OUTPUT_PREFIXES, OPTION_SKIP_OUTPUT_PREFIXES, true, " number of directory prefix to skip in the output file (if supported by outputter");
76 | numberOfOutputPrefixesToSkip.setRequired(false);
77 |
78 |
79 | Option numberOfPrefixesToSkip1 = new Option(OPTION_SKIP_PREFIX1, OPTION_SKIP_PREFIX1, true, " number of directory prefix to skip for the first file");
80 | numberOfPrefixesToSkip1.setRequired(false);
81 |
82 | Option numberOfPrefixesToSkip2 = new Option(OPTION_SKIP_PREFIX2, OPTION_SKIP_PREFIX2, true, " number of directory prefix to skip for the second file");
83 | numberOfPrefixesToSkip2.setRequired(false);
84 |
85 | Option outputFileOption = new Option(OPTION_OUTPUT_FILE, OPTION_OUTPUT_FILE, true, "output filename");
86 | outputFileOption.setRequired(false);
87 |
88 | Option regex = new Option(OPTION_REGEX, OPTION_REGEX, true, "regular expression to match files to exclude e.g. (?i)meta-inf.*");
89 | regex.setRequired(false);
90 |
91 | Option ignoreCVSFilesOption = new Option(OPTION_IGNORE_CVS_FILES, OPTION_IGNORE_CVS_FILES, false, "ignore CVS files");
92 | ignoreCVSFilesOption.setRequired(false);
93 |
94 | Option exitWithError = new Option(OPTION_EXIT_WITH_ERROR_ON_DIFF, OPTION_EXIT_WITH_ERROR_ON_DIFF, false, "if a difference is found then exit with error " + EXITCODE_DIFF);
95 |
96 | Option verboseOption = new Option(OPTION_VERBOSE, OPTION_VERBOSE, false, "verbose mode");
97 |
98 | options.addOption(compareTS);
99 | options.addOption(compareCRC);
100 | options.addOption(file1);
101 | options.addOption(file2);
102 | options.addOption(numberOfOutputPrefixesToSkip);
103 | options.addOption(numberOfPrefixesToSkip1);
104 | options.addOption(numberOfPrefixesToSkip2);
105 | options.addOption(regex);
106 | options.addOption(ignoreCVSFilesOption);
107 | options.addOption(exitWithError);
108 | options.addOption(verboseOption);
109 | options.addOption(outputFileOption);
110 | }
111 |
112 | private static void checkFile(java.io.File f) {
113 | String filename = f.toString();
114 |
115 | if (!f.exists()) {
116 | System.err.println("'" + filename + "' does not exist");
117 | System.exit(EXITCODE_ERROR);
118 | }
119 |
120 | if (!f.canRead()) {
121 | System.err.println("'" + filename + "' is not readable");
122 | System.exit(EXITCODE_ERROR);
123 | }
124 |
125 | if (f.isDirectory()) {
126 | System.err.println("'" + filename + "' is a directory");
127 | System.exit(EXITCODE_ERROR);
128 | }
129 |
130 | }
131 |
132 | private static void writeOutputFile(String filename, int numberOfOutputPrefixesToSkip, Differences d) throws java.io.IOException {
133 | Builder builder = BuilderFactory.create(filename);
134 | builder.build(filename, numberOfOutputPrefixesToSkip, d);
135 | }
136 |
137 | /**
138 | *
139 | * The command line interface to zipdiff utility
140 | *
141 | * @param args The command line parameters
142 | *
143 | */
144 | public static void main(String[] args) {
145 | CommandLineParser parser = new GnuParser();
146 |
147 | try {
148 | CommandLine line = parser.parse(options, args);
149 |
150 | String filename1 = null;
151 | String filename2 = null;
152 |
153 | filename1 = line.getOptionValue(OPTION_FILE1);
154 | filename2 = line.getOptionValue(OPTION_FILE2);
155 |
156 | File f1 = new File(filename1);
157 | File f2 = new File(filename2);
158 |
159 | checkFile(f1);
160 | checkFile(f2);
161 |
162 | System.out.println("File 1 = " + f1);
163 | System.out.println("File 2 = " + f2);
164 |
165 | DifferenceCalculator calc = new DifferenceCalculator(f1, f2);
166 |
167 | int numberOfPrefixesToSkip1 = 0;
168 | if (line.getOptionValue(OPTION_SKIP_PREFIX1) != null) {
169 | numberOfPrefixesToSkip1 = Integer.parseInt(line.getOptionValue(OPTION_SKIP_PREFIX1));
170 | }
171 | int numberOfPrefixesToSkip2 = 0;
172 | if (line.getOptionValue(OPTION_SKIP_PREFIX2) != null) {
173 | numberOfPrefixesToSkip2 = Integer.parseInt(line.getOptionValue(OPTION_SKIP_PREFIX2));
174 | }
175 | int numberOfOutputPrefixesToSkip = 0;
176 | if (line.getOptionValue(OPTION_SKIP_OUTPUT_PREFIXES) != null) {
177 | numberOfOutputPrefixesToSkip = Integer.parseInt(line.getOptionValue(OPTION_SKIP_OUTPUT_PREFIXES));
178 | }
179 |
180 | calc.setNumberOfPrefixesToSkip1(numberOfPrefixesToSkip1);
181 | calc.setNumberOfPrefixesToSkip2(numberOfPrefixesToSkip2);
182 |
183 | String regularExpression = null;
184 |
185 | // todo - calc.setFilenamesToIgnore();
186 |
187 | if (line.hasOption(OPTION_COMPARE_CRC_VALUES)) {
188 | calc.setCompareCRCValues(true);
189 | } else {
190 | calc.setCompareCRCValues(false);
191 | }
192 |
193 | if (line.hasOption(OPTION_IGNORE_CVS_FILES)) {
194 | calc.setIgnoreCVSFiles(true);
195 | } else {
196 | calc.setIgnoreCVSFiles(false);
197 | }
198 |
199 | if (line.hasOption(OPTION_COMPARE_TIMESTAMPS)) {
200 | calc.setIgnoreTimestamps(false);
201 | } else {
202 | calc.setIgnoreTimestamps(true);
203 | }
204 |
205 | if (line.hasOption(OPTION_REGEX)) {
206 | regularExpression = line.getOptionValue(OPTION_REGEX);
207 | Set regexSet = new HashSet();
208 | regexSet.add(regularExpression);
209 |
210 | calc.setFilenameRegexToIgnore(regexSet);
211 | }
212 |
213 | boolean exitWithErrorOnDiff = false;
214 | if (line.hasOption(OPTION_EXIT_WITH_ERROR_ON_DIFF)) {
215 | exitWithErrorOnDiff = true;
216 | }
217 |
218 | Differences d = calc.getDifferences();
219 |
220 | if (line.hasOption(OPTION_OUTPUT_FILE)) {
221 | String outputFilename = line.getOptionValue(OPTION_OUTPUT_FILE);
222 | writeOutputFile(outputFilename, numberOfOutputPrefixesToSkip, d);
223 | }
224 |
225 |
226 | if (d.hasDifferences()) {
227 | if (line.hasOption(OPTION_VERBOSE)) {
228 | System.out.println(d);
229 | System.out.println(d.getFilename1() + " and " + d.getFilename2() + " are different.");
230 | }
231 | if (exitWithErrorOnDiff) {
232 | System.exit(EXITCODE_DIFF);
233 | }
234 | } else {
235 | System.out.println("No differences found.");
236 | }
237 | } catch (ParseException pex) {
238 | System.err.println(pex.getMessage());
239 | HelpFormatter formatter = new HelpFormatter();
240 | formatter.printHelp("zipdiff.Main [options] ", options);
241 | System.exit(EXITCODE_ERROR);
242 | } catch (Exception ex) {
243 | ex.printStackTrace();
244 | System.exit(EXITCODE_ERROR);
245 | }
246 |
247 | }
248 |
249 | }
250 |
--------------------------------------------------------------------------------
/src/main/zipdiff/ant/ZipDiffTask.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.ant;
7 |
8 | import java.io.IOException;
9 |
10 | import org.apache.tools.ant.BuildException;
11 | import org.apache.tools.ant.Task;
12 |
13 | import zipdiff.DifferenceCalculator;
14 | import zipdiff.Differences;
15 | import zipdiff.output.Builder;
16 | import zipdiff.output.BuilderFactory;
17 |
18 | /**
19 | * Ant task for running zipdiff from a build.xml file
20 | *
21 | *
22 | * @author Sean C. Sullivan
23 | */
24 | public class ZipDiffTask extends Task {
25 | private String filename1;
26 |
27 | private String filename2;
28 |
29 | private int numberOfOutputPrefixesToSkip;
30 |
31 | private int skipPrefixes1 = 0;
32 |
33 | private int SkipPrefixes2 = 0;
34 |
35 | private String destfile;
36 |
37 | private boolean ignoreTimestamps = false;
38 |
39 | private boolean ignoreCVSFiles = false;
40 |
41 | private boolean compareCRCValues = true;
42 |
43 | public void setFilename1(String name) {
44 | filename1 = name;
45 | }
46 |
47 | public void setFilename2(String name) {
48 | filename2 = name;
49 | }
50 |
51 |
52 |
53 | public int getNumberOfOutputPrefixesToSkip() {
54 | return numberOfOutputPrefixesToSkip;
55 | }
56 |
57 | public void setNumberOfOutputPrefixesToSkip(int numberOfOutputPrefixesToSkip) {
58 | this.numberOfOutputPrefixesToSkip = numberOfOutputPrefixesToSkip;
59 | }
60 |
61 | public int getSkipPrefixes1() {
62 | return skipPrefixes1;
63 | }
64 |
65 | public void setSkipPrefixes1(int numberOfPrefixesToSkip1) {
66 | this.skipPrefixes1 = numberOfPrefixesToSkip1;
67 | }
68 |
69 | public int getSkipPrefixes2() {
70 | return SkipPrefixes2;
71 | }
72 |
73 | public void setSkipPrefixes2(int numberOfPrefixesToSkip2) {
74 | this.SkipPrefixes2 = numberOfPrefixesToSkip2;
75 | }
76 |
77 | public void setIgnoreTimestamps(boolean b) {
78 | ignoreTimestamps = b;
79 | }
80 |
81 | public boolean getIgnoreTimestamps() {
82 | return ignoreTimestamps;
83 | }
84 |
85 | public void setIgnoreCVSFiles(boolean b) {
86 | ignoreCVSFiles = b;
87 | }
88 |
89 | public boolean getIgnoreCVSFiles() {
90 | return ignoreCVSFiles;
91 | }
92 |
93 | public void setCompareCRCValues(boolean b) {
94 | compareCRCValues = b;
95 | }
96 |
97 | public boolean getCompareCRCValues() {
98 | return compareCRCValues;
99 | }
100 |
101 | @Override
102 | public void execute() throws BuildException {
103 | validate();
104 |
105 | // this.log("Filename1=" + filename1, Project.MSG_DEBUG);
106 | // this.log("Filename2=" + filename2, Project.MSG_DEBUG);
107 | // this.log("destfile=" + getDestFile(), Project.MSG_DEBUG);
108 |
109 | Differences d = calculateDifferences();
110 |
111 | try {
112 | writeDestFile(d);
113 | } catch (java.io.IOException ex) {
114 | throw new BuildException(ex);
115 | }
116 |
117 | }
118 |
119 | /**
120 | * writes the output file
121 | *
122 | * @param d set of Differences
123 | * @throws IOException
124 | */
125 | protected void writeDestFile(Differences d) throws IOException {
126 | String destfilename = getDestFile();
127 | Builder builder = BuilderFactory.create(destfilename);
128 | builder.build(destfilename, numberOfOutputPrefixesToSkip, d);
129 | }
130 |
131 | /**
132 | * gets the name of the target file
133 | *
134 | * @return target file
135 | */
136 | public String getDestFile() {
137 | return destfile;
138 | }
139 |
140 | /**
141 | * sets the name of the target file
142 | *
143 | * @param name filename
144 | */
145 | public void setDestFile(String name) {
146 | destfile = name;
147 | }
148 |
149 | /**
150 | * calculates the differences
151 | *
152 | * @return set of Differences
153 | * @throws BuildException in case of an input/output error
154 | */
155 | protected Differences calculateDifferences() throws BuildException {
156 | DifferenceCalculator calculator;
157 |
158 | Differences d = null;
159 |
160 | try {
161 | calculator = new DifferenceCalculator(filename1, filename2);
162 | calculator.setNumberOfPrefixesToSkip1(skipPrefixes1);
163 | calculator.setNumberOfPrefixesToSkip2(SkipPrefixes2);
164 | calculator.setCompareCRCValues(getCompareCRCValues());
165 | calculator.setIgnoreTimestamps(getIgnoreTimestamps());
166 | calculator.setIgnoreCVSFiles(getIgnoreCVSFiles());
167 |
168 | // todo : calculator.setFilenamesToIgnore(patterns);
169 |
170 | d = calculator.getDifferences();
171 | } catch (IOException ex) {
172 | throw new BuildException(ex);
173 | }
174 |
175 | return d;
176 | }
177 |
178 | /**
179 | * validates the parameters
180 | *
181 | * @throws BuildException in case of invalid parameters
182 | */
183 | protected void validate() throws BuildException {
184 | if ((filename1 == null) || (filename1.length() < 1)) {
185 | throw new BuildException("filename1 is required");
186 | }
187 |
188 | if ((filename2 == null) || (filename2.length() < 1)) {
189 | throw new BuildException("filename2 is required");
190 | }
191 |
192 | String destinationfile = getDestFile();
193 |
194 | if ((destinationfile == null) || (destinationfile.length() < 1)) {
195 | throw new BuildException("destfile is required");
196 | }
197 | }
198 |
199 | }
200 |
--------------------------------------------------------------------------------
/src/main/zipdiff/ant/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 | Provides ant tasks for the zipdiff utility.
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/AbstractBuilder.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 | import java.io.OutputStream;
11 |
12 | import zipdiff.Differences;
13 |
14 | /**
15 | * abstract base class for Builders.
16 | *
17 | * @author Sean C. Sullivan, Hendrik Brummermann
18 | */
19 | public abstract class AbstractBuilder implements Builder {
20 |
21 | /** number of directory prefixes to skip in the output file */
22 | protected int numberOfOutputPrefixesToSkip;
23 |
24 | /**
25 | * builds the output
26 | *
27 | * @param filename name of output file
28 | * @param numberOfPrefixesToSkip number of directory prefixes to skip
29 | * @param d differences
30 | * @throws IOException in case of an input/output error
31 | */
32 | public void build(String filename, int numberOfPrefixesToSkip, Differences d) throws IOException {
33 | this.numberOfOutputPrefixesToSkip = numberOfPrefixesToSkip;
34 | OutputStream os = null;
35 | if ((filename == null) || filename.equals("-")) {
36 | os = System.out;
37 | } else {
38 | os = new FileOutputStream(filename);
39 | }
40 | build(os, d);
41 | os.flush();
42 | }
43 |
44 | /**
45 | * builds the output
46 | *
47 | * @param out OutputStream to write to
48 | * @param d differences
49 | */
50 | public abstract void build(OutputStream out, Differences d);
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/Builder.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | import java.io.IOException;
9 |
10 | import zipdiff.Differences;
11 |
12 | /**
13 | * Builder pattern:
14 | * http://wiki.cs.uiuc.edu/patternStories/BuilderPattern
15 | *
16 | * @author Sean C. Sullivan
17 | */
18 | public interface Builder {
19 |
20 | /**
21 | * builds the output
22 | *
23 | * @param filename name of output file
24 | * @param numberOfOutputPrefixesToSkip number of directory prefixes to skip
25 | * @param d differences
26 | * @throws IOException in case of an input/output error
27 | */
28 | public void build(String filename, int numberOfOutputPrefixesToSkip, Differences d) throws IOException;
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/BuilderFactory.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | /**
9 | * creates builders based on the filename extension.
10 | *
11 | * @author Hendrik Brummermann, HIS GmbH
12 | */
13 | public class BuilderFactory {
14 |
15 | /**
16 | * creates a builder based on the name of the output file
17 | *
18 | * @param filename name of output file
19 | * @return Builder
20 | */
21 | public static Builder create(String filename) {
22 | Builder builder = null;
23 |
24 | if ((filename == null) || filename.equals("-")) {
25 | builder = new TextBuilder();
26 |
27 | } else if (filename.endsWith(".html")) {
28 | builder = new HtmlBuilder();
29 |
30 | } else if (filename.endsWith(".txt")) {
31 | builder = new TextBuilder();
32 |
33 | } else if (filename.endsWith(".xml")) {
34 | builder = new XmlBuilder();
35 |
36 | } else if (filename.endsWith(".zip")) {
37 | builder = new ZipBuilder();
38 |
39 | } else {
40 | System.err.println("Unknown extension, using text output");
41 | builder = new TextBuilder();
42 | }
43 | return builder;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/HtmlBuilder.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | import java.io.OutputStream;
9 | import java.io.PrintWriter;
10 | import java.util.Iterator;
11 | import java.util.Set;
12 |
13 | import zipdiff.Differences;
14 |
15 | /**
16 | * Generates html output for a Differences instance
17 | *
18 | * @author Sean C. Sullivan
19 | */
20 | public class HtmlBuilder extends AbstractBuilder {
21 |
22 | /**
23 | * builds the output
24 | *
25 | * @param out OutputStream to write to
26 | * @param d differences
27 | */
28 | @Override
29 | public void build(OutputStream out, Differences d) {
30 | PrintWriter pw = new PrintWriter(out);
31 |
32 | pw.println("");
33 | pw.println(" ");
34 | pw.println("");
35 | pw.println("File differences ");
36 | pw.println("");
37 |
38 | pw.println("");
39 |
40 | pw.println(getStyleTag());
41 | pw.print("First file: ");
42 | String filename1 = d.getFilename1();
43 |
44 | if (filename1 == null) {
45 | filename1 = "filename1.zip";
46 | }
47 | pw.print(filename1);
48 | pw.println(" ");
49 |
50 | pw.print("Second file: ");
51 |
52 | String filename2 = d.getFilename2();
53 |
54 | if (filename2 == null) {
55 | filename2 = "filename2.zip";
56 | }
57 | pw.print(filename2);
58 | pw.println("
");
59 |
60 | writeAdded(pw, d.getAdded().keySet());
61 | writeRemoved(pw, d.getRemoved().keySet());
62 | writeChanged(pw, d.getChanged().keySet());
63 | pw.println(" ");
64 | pw.println("");
65 | pw.println("Generated at " + new java.util.Date());
66 | pw.println("
");
67 | pw.println("");
68 |
69 | pw.println("");
70 |
71 | pw.flush();
72 |
73 | }
74 |
75 | /**
76 | * writes the list of added files
77 | *
78 | * @param pw write to write to
79 | * @param added set of added files
80 | */
81 | protected void writeAdded(PrintWriter pw, Set added) {
82 | writeDiffSet(pw, "Added", added);
83 | }
84 |
85 | /**
86 | * writes the list of removed files
87 | *
88 | * @param pw write to write to
89 | * @param removed set of removed files
90 | */
91 | protected void writeRemoved(PrintWriter pw, Set removed) {
92 | writeDiffSet(pw, "Removed", removed);
93 | }
94 |
95 | /**
96 | * writes the list of modified files
97 | *
98 | * @param pw write to write to
99 | * @param changed set of modified files
100 | */
101 | protected void writeChanged(PrintWriter pw, Set changed) {
102 | writeDiffSet(pw, "Changed", changed);
103 | }
104 |
105 | /**
106 | * writes a set of differences
107 | *
108 | * @param pw write to write to
109 | * @param name heading
110 | * @param s set
111 | */
112 | protected void writeDiffSet(PrintWriter pw, String name, Set s) {
113 | pw.println("");
114 | pw.println("");
115 | pw.println("" + name + " (" + s.size() + " entries) ");
116 | pw.println(" ");
117 | pw.println("");
118 | pw.println("");
119 | pw.println(" ");
120 | pw.println("");
121 | if (s.size() > 0) {
122 | pw.println("");
123 | Iterator iter = s.iterator();
124 | while (iter.hasNext()) {
125 | String key = (String) iter.next();
126 | pw.print("");
127 | pw.print(key);
128 | pw.println(" ");
129 | }
130 | pw.println(" ");
131 | }
132 | pw.println(" ");
133 | pw.println(" ");
134 | pw.println("
");
135 |
136 | }
137 |
138 | /**
139 | * generates the style-html-tag.
140 | *
141 | * @return content of style-tag
142 | */
143 | protected String getStyleTag() {
144 | StringBuffer sb = new StringBuffer();
145 |
146 | sb.append("\n");
165 |
166 | return sb.toString();
167 | }
168 |
169 | }
170 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/TextBuilder.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | import java.io.OutputStream;
9 | import java.io.PrintWriter;
10 |
11 | import zipdiff.Differences;
12 |
13 | /**
14 | * creates a list of differences.
15 | *
16 | * @author Sean C. Sullivan
17 | */
18 | public class TextBuilder extends AbstractBuilder {
19 |
20 | /**
21 | * builds the output
22 | *
23 | * @param out OutputStream to write to
24 | * @param d differences
25 | */
26 | @Override
27 | public void build(OutputStream out, Differences d) {
28 | PrintWriter pw = new PrintWriter(out);
29 | pw.println(d.toString());
30 | pw.flush();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/XmlBuilder.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | import java.io.OutputStream;
9 | import java.io.PrintWriter;
10 | import java.util.Iterator;
11 | import java.util.Set;
12 |
13 | import zipdiff.Differences;
14 |
15 | /**
16 | *
17 | * Generates xml output for a Differences instance
18 | *
19 | * @author Sean C. Sullivan
20 | *
21 | */
22 | public class XmlBuilder extends AbstractBuilder {
23 |
24 | /**
25 | * builds the output
26 | *
27 | * @param out OutputStream to write to
28 | * @param d differences
29 | */
30 | @Override
31 | public void build(OutputStream out, Differences d) {
32 | PrintWriter pw = new PrintWriter(out);
33 |
34 | pw.println("");
35 | pw.print("");
52 |
53 | pw.println("");
54 | writeAdded(pw, d.getAdded().keySet());
55 | writeRemoved(pw, d.getRemoved().keySet());
56 | writeChanged(pw, d.getChanged().keySet());
57 | pw.println(" ");
58 | pw.println(" ");
59 |
60 | pw.flush();
61 | }
62 |
63 | /**
64 | * writes the list of added files
65 | *
66 | * @param pw write to write to
67 | * @param added set of added files
68 | */
69 | protected void writeAdded(PrintWriter pw, Set added) {
70 | Iterator iter = added.iterator();
71 | while (iter.hasNext()) {
72 | String key = (String) iter.next();
73 | pw.print("");
74 | pw.print(key);
75 | pw.println(" ");
76 | }
77 |
78 | }
79 |
80 | /**
81 | * writes the list of removed files
82 | *
83 | * @param pw write to write to
84 | * @param removed set of removed files
85 | */
86 | protected void writeRemoved(PrintWriter pw, Set removed) {
87 | Iterator iter = removed.iterator();
88 | while (iter.hasNext()) {
89 | String key = (String) iter.next();
90 | pw.print("");
91 | pw.print(key);
92 | pw.println(" ");
93 | }
94 | }
95 |
96 | /**
97 | * writes the list of modified files
98 | *
99 | * @param pw write to write to
100 | * @param changed set of modified files
101 | */
102 | protected void writeChanged(PrintWriter pw, Set changed) {
103 | Iterator iter = changed.iterator();
104 | while (iter.hasNext()) {
105 | String key = (String) iter.next();
106 | pw.print("");
107 | pw.print(key);
108 | pw.println(" ");
109 | }
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/ZipBuilder.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.output;
7 |
8 | import java.io.IOException;
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 | import java.util.Iterator;
12 | import java.util.Map;
13 | import java.util.Set;
14 | import java.util.TreeSet;
15 | import java.util.zip.ZipEntry;
16 | import java.util.zip.ZipFile;
17 | import java.util.zip.ZipOutputStream;
18 |
19 | import zipdiff.Differences;
20 | import zipdiff.util.StringUtil;
21 |
22 | /**
23 | * creates a zip file with the new versions of files that have been added or modified
24 | *
25 | * @author Hendrik Brummermann, HIS GmbH
26 | */
27 | public class ZipBuilder extends AbstractBuilder {
28 | private Differences differences;
29 |
30 | private final Set filenames = new TreeSet();
31 |
32 | /**
33 | * builds the output
34 | *
35 | * @param out OutputStream to write to
36 | * @param d differences
37 | */
38 | @Override
39 | public void build(OutputStream out, Differences d) {
40 | differences = d;
41 | try {
42 | collectAddedFiles();
43 | collectModifiedFiles();
44 | copyEntries(out);
45 | } catch (IOException e) {
46 | System.err.println("Error while writing zip file: " + e);
47 | e.printStackTrace();
48 | }
49 | }
50 |
51 | /**
52 | * collects all the files that have been added in the second zip archive
53 | */
54 | private void collectAddedFiles() {
55 | Set entrySet = differences.getAdded().entrySet();
56 | Iterator itr = entrySet.iterator();
57 | while (itr.hasNext()) {
58 | Map.Entry mapEntry = (Map.Entry) itr.next();
59 | if (mapEntry.getKey().toString().indexOf("!") < 0) {
60 | filenames.add(((ZipEntry) mapEntry.getValue()).getName());
61 | }
62 | }
63 | }
64 |
65 | /**
66 | * collects all the files that have been added modified in the second zip archive
67 | */
68 | private void collectModifiedFiles() {
69 | Set entrySet = differences.getChanged().entrySet();
70 | Iterator itr = entrySet.iterator();
71 | while (itr.hasNext()) {
72 | Map.Entry mapEntry = (Map.Entry) itr.next();
73 | if (mapEntry.getKey().toString().indexOf("!") < 0) {
74 | filenames.add(((ZipEntry[]) mapEntry.getValue())[1].getName());
75 | }
76 | }
77 | }
78 |
79 | /**
80 | * copies the zip entries (with data) from the second archive file to the output file.
81 | *
82 | * @param out output file
83 | * @throws IOException in case of an input/output error
84 | */
85 | private void copyEntries(OutputStream out) throws IOException {
86 | ZipOutputStream os = new ZipOutputStream(out);
87 | ZipFile zipFile = new ZipFile(differences.getFilename2());
88 | Iterator itr = filenames.iterator();
89 |
90 | while (itr.hasNext()) {
91 | String filename = (String) itr.next();
92 | ZipEntry zipEntry = zipFile.getEntry(filename);
93 | InputStream is = zipFile.getInputStream(zipEntry);
94 | ZipEntry z = new ZipEntry(StringUtil.removeDirectoryPrefix(filename, numberOfOutputPrefixesToSkip));
95 | os.putNextEntry(z);
96 | copyStream(is, os);
97 | os.closeEntry();
98 | is.close();
99 | }
100 |
101 | zipFile.close();
102 | os.close();
103 | }
104 |
105 | /**
106 | * copies data from an input stream to an output stream
107 | *
108 | * @param input InputStream
109 | * @param output OutputStream
110 | * @throws IOException in case of an input/output error
111 | */
112 | private void copyStream(InputStream input, OutputStream output) throws IOException {
113 | byte buffer[] = new byte[4096];
114 | int count = input.read(buffer);
115 | while (count > -1) {
116 | output.write(buffer, 0, count);
117 | count = input.read(buffer);
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/src/main/zipdiff/output/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 | Provides the interface and implementations used for formatting the output of the zipdiff Ant tasks.
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/main/zipdiff/package.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
10 |
11 |
12 | Utilities for comparing the contents of 2 different zip files.
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/main/zipdiff/util/StringUtil.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff.util;
7 |
8 | /**
9 | * String manipulation methods
10 | *
11 | * @author Hendrik Brummermann
12 | */
13 | public class StringUtil {
14 |
15 | /**
16 | * removes the specified number of prefix components from a path
17 | * @param name file name with path
18 | * @param number number of directory prefixed to remove
19 | * @return path without prefix
20 | */
21 | public static String removeDirectoryPrefix(String name, int number) {
22 | int pos = 0;
23 | for (int i = 0; i < number; i++) {
24 | pos = name.indexOf("/", pos) + 1;
25 | }
26 | if (pos < 0) {
27 | return null;
28 | }
29 | return name.substring(pos);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/metadata/JAR-manifest.txt:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Created-By: Sean C. Sullivan
3 | Class-Path: commons-cli-1.0.jar
4 | Main-Class: zipdiff.Main
5 |
--------------------------------------------------------------------------------
/src/test/zipdiff/DifferenceCalculatorTest.java:
--------------------------------------------------------------------------------
1 | /* zipdiff is available under the terms of the
2 | * Apache License, version 2.0
3 | *
4 | * Link: http://www.apache.org/licenses/
5 | */
6 | package zipdiff;
7 |
8 | import java.io.BufferedOutputStream;
9 | import java.io.ByteArrayOutputStream;
10 | import java.io.File;
11 | import java.io.FileNotFoundException;
12 | import java.io.FileOutputStream;
13 | import java.io.IOException;
14 | import java.util.Map;
15 | import java.util.jar.JarEntry;
16 | import java.util.jar.JarOutputStream;
17 |
18 | import junit.framework.TestCase;
19 | import zipdiff.output.AbstractBuilder;
20 | import zipdiff.output.HtmlBuilder;
21 | import zipdiff.output.TextBuilder;
22 | import zipdiff.output.XmlBuilder;
23 |
24 | /**
25 | * tests for DifferenceCalculator
26 | *
27 | * @author jastewart
28 | */
29 | public class DifferenceCalculatorTest extends TestCase {
30 | private static String ENTRYA = "A";
31 |
32 | private static String ENTRYB = "B";
33 |
34 | private static String ENTRY_CVS = "CVS/Root";
35 |
36 | public static final String SYSTEM_TMP_DIR_PROPERTY = "java.io.tmpdir";
37 |
38 | public static final String TEST_DIR_POSTFIX = File.separator + "UnitTestsDifferenceCalculatorTest";
39 |
40 | private static String testDirPathName;
41 |
42 | // naming convention The Capital letter denotes the entry so A will be the same as A
43 | // OneEntry denotes that the jar has one entry
44 | private static String testJarOneEntryA1Filename;
45 |
46 | private static String testJarOneEntryA2Filename;
47 |
48 | private static String testJarOneEntryB1Filename;
49 |
50 | private static String testJarOneEntryAContentsChangedFilename;
51 |
52 | {
53 | testDirPathName = System.getProperty(SYSTEM_TMP_DIR_PROPERTY);
54 | if (testDirPathName == null) {
55 | testDirPathName = File.separator + "temp" + TEST_DIR_POSTFIX;
56 | }
57 | testJarOneEntryA1Filename = testDirPathName + File.separator + "testJarOneEntryA1Filename.jar";
58 | testJarOneEntryA2Filename = testDirPathName + File.separator + "testJarOneEntryA2Filename.jar";
59 | testJarOneEntryB1Filename = testDirPathName + File.separator + "testJarOneEntryB1Filename.jar";
60 | testJarOneEntryAContentsChangedFilename = testDirPathName + File.separator + "testJarOneEntryAContentsChangedFilename.jar";
61 | }
62 |
63 | /**
64 | * Create a jar with only one entry in it. That entry being A
65 | *
66 | * @throws FileNotFoundException
67 | * @throws IOException
68 | */
69 | public void createJarOneEntryA1() throws FileNotFoundException, IOException {
70 | // create a jar file with no duplicates
71 | File testDir = new File(testDirPathName);
72 | testDir.mkdirs();
73 | JarOutputStream testJarOS = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(testJarOneEntryA1Filename)));
74 |
75 | // ad an entry
76 | JarEntry entry1 = new JarEntry(ENTRYA);
77 | testJarOS.putNextEntry(entry1);
78 | byte data1[] = new byte[2048];
79 | for (int i = 0; i < data1.length; i++) {
80 | data1[i] = 'a';
81 | }
82 | testJarOS.write(data1);
83 |
84 | testJarOS.flush();
85 | testJarOS.close();
86 | }
87 |
88 | /**
89 | * Create a jar with only one entry in it. That entry being A
90 | *
91 | * @throws FileNotFoundException
92 | * @throws IOException
93 | */
94 | public void createJarOneEntryA2() throws FileNotFoundException, IOException {
95 | // create a jar file with no duplicates
96 | File testDir = new File(testDirPathName);
97 | testDir.mkdirs();
98 | JarOutputStream testJarOS = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(testJarOneEntryA2Filename)));
99 |
100 | // ad an entry
101 | JarEntry entry1 = new JarEntry(ENTRYA);
102 | testJarOS.putNextEntry(entry1);
103 | byte data1[] = new byte[2048];
104 | for (int i = 0; i < data1.length; i++) {
105 | data1[i] = 'a';
106 | }
107 | testJarOS.write(data1);
108 |
109 | testJarOS.flush();
110 | testJarOS.close();
111 | }
112 |
113 | /**
114 | * Create a jar with only one entry in it. That entry being A
115 | *
116 | * @throws FileNotFoundException
117 | * @throws IOException
118 | */
119 | public void createJarOneEntryAContentsChanged() throws FileNotFoundException, IOException {
120 | // create a jar file with no duplicates
121 | File testDir = new File(testDirPathName);
122 | testDir.mkdirs();
123 | JarOutputStream testJarOS = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(testJarOneEntryAContentsChangedFilename)));
124 |
125 | // add an entry
126 | JarEntry entry1 = new JarEntry(ENTRYA);
127 | testJarOS.putNextEntry(entry1);
128 | byte data1[] = new byte[2048];
129 | for (int i = 0; i < data1.length; i++) {
130 | data1[i] = 'a';
131 | }
132 | // set a different content so that it will come up as changed
133 | data1[data1.length - 1] = 'b';
134 | testJarOS.write(data1);
135 |
136 | // add another entry
137 | JarEntry cvs = new JarEntry(ENTRY_CVS);
138 | testJarOS.putNextEntry(cvs);
139 |
140 | testJarOS.flush();
141 | testJarOS.close();
142 | }
143 |
144 | /**
145 | * Create a jar with only one entry in it. That entry being A
146 | *
147 | * @throws FileNotFoundException
148 | * @throws IOException
149 | */
150 | public void createJarOneEntryB1() throws FileNotFoundException, IOException {
151 | // create a jar file with no duplicates
152 | File testDir = new File(testDirPathName);
153 | testDir.mkdirs();
154 | JarOutputStream testJarOS = new JarOutputStream(new BufferedOutputStream(new FileOutputStream(testJarOneEntryB1Filename)));
155 |
156 | // ad an entry
157 | JarEntry entry1 = new JarEntry(ENTRYB);
158 | testJarOS.putNextEntry(entry1);
159 | byte data1[] = new byte[2048];
160 | for (int i = 0; i < data1.length; i++) {
161 | data1[i] = 'b';
162 | }
163 | testJarOS.write(data1);
164 |
165 | testJarOS.flush();
166 | testJarOS.close();
167 | }
168 |
169 |
170 | /**
171 | * Test for Differences calculateDifferences(ZipFile, ZipFile)
172 | * with the same file - no differences should be found
173 | */
174 | public void testCalculateDifferencesSameZip() throws FileNotFoundException, IOException {
175 | createJarOneEntryA1();
176 | DifferenceCalculator calc = new DifferenceCalculator(testJarOneEntryA1Filename, testJarOneEntryA1Filename);
177 | Differences differences = calc.getDifferences();
178 | assertFalse(differences.hasDifferences());
179 | Map addedEntries = differences.getAdded();
180 | assertTrue(addedEntries.size() == 0);
181 | Map removedEntries = differences.getRemoved();
182 | assertTrue(removedEntries.size() == 0);
183 | Map changedEntries = differences.getChanged();
184 | assertTrue(changedEntries.size() == 0);
185 |
186 | exerciseOutputBuilders(differences);
187 |
188 | }
189 |
190 | /**
191 | * Test for Differences calculateDifferences(ZipFile, ZipFile)
192 | */
193 | public void testCalculateDifferencesZipsSameEntries() throws FileNotFoundException, IOException {
194 | createJarOneEntryA1();
195 | createJarOneEntryA2();
196 | DifferenceCalculator calc = new DifferenceCalculator(testJarOneEntryA1Filename, testJarOneEntryA2Filename);
197 | Differences differences = calc.getDifferences();
198 | assertFalse(differences.hasDifferences());
199 | Map addedEntries = differences.getAdded();
200 | assertTrue(addedEntries.size() == 0);
201 | Map removedEntries = differences.getRemoved();
202 | assertTrue(removedEntries.size() == 0);
203 | Map changedEntries = differences.getChanged();
204 | assertTrue(changedEntries.size() == 0);
205 |
206 | exerciseOutputBuilders(differences);
207 | }
208 |
209 | /**
210 | * Test for Differences calculateDifferences(ZipFile, ZipFile)
211 | * Test that the differences between two zips with A in one and B in the second.
212 | * A will have been removed and B will have been added.
213 | */
214 | public void testCalculateDifferencesZipsDifferentEntries() throws FileNotFoundException, IOException {
215 | createJarOneEntryA1();
216 | createJarOneEntryB1();
217 | DifferenceCalculator calc = new DifferenceCalculator(testJarOneEntryA1Filename, testJarOneEntryB1Filename);
218 | Differences differences = calc.getDifferences();
219 | assertTrue(differences.hasDifferences());
220 | Map addedEntries = differences.getAdded();
221 | assertTrue(addedEntries.containsKey("B"));
222 | Map removedEntries = differences.getRemoved();
223 | assertTrue(removedEntries.containsKey("A"));
224 | Map changedEntries = differences.getChanged();
225 | assertTrue(changedEntries.size() == 0);
226 |
227 | exerciseOutputBuilders(differences);
228 |
229 | }
230 |
231 |
232 | /**
233 | * Test for Differences calculateDifferences(ZipFile, ZipFile)
234 | * Test that the differences between two zips with A in one and A in the second with different content.
235 | * A will have been removed and B will have been added.
236 | */
237 | public void testCalculateDifferencesZipsSameEntriesDifferentContent() throws FileNotFoundException, IOException {
238 | createJarOneEntryA1();
239 | createJarOneEntryAContentsChanged();
240 | DifferenceCalculator calc = new DifferenceCalculator(testJarOneEntryA1Filename, testJarOneEntryAContentsChangedFilename);
241 | calc.setIgnoreCVSFiles(true);
242 | Differences differences = calc.getDifferences();
243 | assertTrue(differences.hasDifferences());
244 | Map addedEntries = differences.getAdded();
245 | assertTrue(addedEntries.size() == 0);
246 | Map removedEntries = differences.getRemoved();
247 | assertTrue(removedEntries.size() == 0);
248 | Map changedEntries = differences.getChanged();
249 | assertTrue(changedEntries.containsKey("A"));
250 |
251 | exerciseOutputBuilders(differences);
252 |
253 | }
254 |
255 | private void exerciseHtmlBuilder(Differences differences) {
256 | assertNotNull(differences);
257 |
258 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
259 |
260 | AbstractBuilder b = new HtmlBuilder();
261 | b.build(baos, differences);
262 |
263 | assertTrue(baos.size() > 0);
264 | }
265 |
266 | private void exerciseXmlBuilder(Differences differences) {
267 | assertNotNull(differences);
268 |
269 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
270 |
271 | AbstractBuilder b = new XmlBuilder();
272 | b.build(baos, differences);
273 |
274 | assertTrue(baos.size() > 0);
275 | }
276 |
277 | private void exerciseTextBuilder(Differences differences) {
278 | assertNotNull(differences);
279 |
280 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
281 |
282 | AbstractBuilder b = new TextBuilder();
283 | b.build(baos, differences);
284 |
285 | assertTrue(baos.size() > 0);
286 | }
287 |
288 | private void exerciseOutputBuilders(Differences differences) {
289 | assertNotNull(differences);
290 | exerciseHtmlBuilder(differences);
291 | exerciseXmlBuilder(differences);
292 | exerciseTextBuilder(differences);
293 | }
294 |
295 | }
296 |
--------------------------------------------------------------------------------
/xdocs/credits.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Credits
6 |
7 |
8 |
9 |
10 |
11 | Sean C. Sullivan - founder of the zipdiff project
12 | James Stewart - unit tests, improved command line options, documentation
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/xdocs/index.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Welcome
7 |
8 |
9 |
10 |
11 |
12 |
13 | Use the zipdiff tool when you need to compare the contents of two zip files.
14 | It is equally suited for comparing jar files, EAR files, WAR files or RAR files.
15 |
16 |
17 | Run it standalone or as an
18 | Ant task.
19 | The tool supports three output formats: plain text, XML, and HTML .
20 |
21 |
22 | zipdiff is written in Java
23 |
24 |
25 | The current version is 0.4
26 |
27 |
28 |
29 |
30 |
31 | java -jar zipdiff.jar -file1 foo.zip -file2 bar.zip [ -outputfile diffs.html ] [ -comparetimestamps ] [ -comparecrcvalues ]
32 |
33 |
34 |
35 |
36 |
37 | <taskdef name="zipdiff" classname="zipdiff.ant.ZipDiffTask"/>
38 |
39 | <zipdiff filename1="foo.zip"
40 | filename2="foo2.zip"
41 | ignoreTimestamps="true"
42 | compareCRCValues="true"
43 | destfile="zipdiff.xml">
44 | </zipdiff>
45 |
46 |
47 |
48 |
49 |
50 |
51 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/xdocs/navigation.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | zipdiff
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/xdocs/output.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Sample output
7 |
8 |
9 |
10 |
11 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/xdocs/related.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Related information
6 |
7 |
8 |
9 |
10 | If you are interested in the zipdiff project, then you might also be
11 | interested in the following:
12 |
13 |
14 |
15 |
28 |
29 |
30 |
31 |
36 |
37 |
38 |
39 |
47 |
48 |
49 |
50 |
58 |
59 |
60 |
61 |
66 |
67 |
68 |
69 |
73 |
74 |
75 |
76 |
79 |
80 |
81 |
82 |
83 |
88 |
89 |
90 |
91 |
95 |
96 |
97 |
98 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/xdocs/sample-output.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | File differences
5 |
6 |
7 |
21 |
22 | First file: c:\a.zip
23 | Second file: c:\b.zip
24 |
25 |
26 | Added (2 entries)
27 |
28 |
29 |
30 |
31 |
32 |
33 | zzz/foo.txt
34 | bar.txt
35 |
36 |
37 |
38 |
39 |
40 |
41 | Removed (0 entries)
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | Changed (3 entries)
53 |
54 |
55 |
56 |
57 |
58 |
59 | my.jar
60 | my.jar/Util.class
61 | hello.txt
62 |
63 |
64 |
65 |
66 |
67 | Generated at Sun Jun 27 14:05:48 GMT-08:00 2004
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/xdocs/tools.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Tools and libraries
7 |
8 |
9 |
10 |
11 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------