Codebase list ivy / f8ef091
Update upstream source from tag 'upstream/2.5.0' Update to upstream version '2.5.0' with Debian dir 5739eb2d94f3fa95bffcd43d04ae0069253b9d68 Emmanuel Bourg 3 years ago
625 changed file(s) with 18641 addition(s) and 14822 deletion(s). Raw diff Collapse all Expand all
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 https://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18 -->
19 <fileset-config file-format-version="1.2.0" simple-config="false">
20 <local-check-config name="Ivy Checkstyle Config" location="src/etc/checkstyle/checkstyle-config" type="project" description="">
21 <property name="checkstyle.src.dir" value="${basedir}/src/etc/checkstyle"/>
22 <additional-data name="protect-config-file" value="true"/>
23 </local-check-config>
24 <fileset name="Ivy Checkstyle config" enabled="true" check-config-name="Ivy Checkstyle Config" local="true">
25 <file-match-pattern match-pattern="^src.java.*.java$" include-pattern="true"/>
26 <file-match-pattern match-pattern="^src.example.*.java$" include-pattern="true"/>
27 <file-match-pattern match-pattern="^test.java.*.java$" include-pattern="true"/>
28 </fileset>
29 </fileset-config>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 https://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18 -->
19 <classpath>
20 <classpathentry kind="src" path="src/java"/>
21 <classpathentry kind="src" path="test/java"/>
22 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
23 <classpathentry kind="lib" path="lib/ant.jar"/>
24 <classpathentry kind="lib" path="lib/ant-testutil.jar"/>
25 <classpathentry kind="lib" path="lib/commons-codec.jar"/>
26 <classpathentry kind="lib" path="lib/commons-logging.jar"/>
27 <classpathentry kind="lib" path="lib/commons-vfs2.jar"/>
28 <classpathentry kind="lib" path="lib/hamcrest-core.jar"/>
29 <classpathentry kind="lib" path="lib/httpclient.jar"/>
30 <classpathentry kind="lib" path="lib/httpcore.jar"/>
31 <classpathentry kind="lib" path="lib/jsch.jar"/>
32 <classpathentry kind="lib" path="lib/junit.jar"/>
33 <classpathentry kind="lib" path="lib/xmlunit.jar"/>
34 <classpathentry kind="lib" path="lib/oro.jar"/>
35 <classpathentry kind="lib" path="lib/bcpg-jdk15on.jar"/>
36 <classpathentry kind="lib" path="lib/bcprov-jdk15on.jar"/>
37 <classpathentry kind="lib" path="lib/jsch.agentproxy.connector-factory.jar"/>
38 <classpathentry kind="lib" path="lib/jsch.agentproxy.core.jar"/>
39 <classpathentry kind="lib" path="lib/jsch.agentproxy.jsch.jar"/>
40 <classpathentry kind="lib" path="lib/jsch.agentproxy.pageant.jar"/>
41 <classpathentry kind="lib" path="lib/jsch.agentproxy.sshagent.jar"/>
42 <classpathentry kind="lib" path="lib/jsch.agentproxy.usocket-jna.jar"/>
43 <classpathentry kind="lib" path="lib/jsch.agentproxy.usocket-nc.jar"/>
44 <classpathentry kind="output" path="bin"/>
45 </classpath>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 https://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18 -->
19 <classpath>
20 <classpathentry kind="src" path="src/java"/>
21 <classpathentry kind="src" path="test/java"/>
22 <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
23 <classpathentry kind="con" path="org.apache.ivyde.eclipse.cpcontainer.IVYDE_CONTAINER/?project=ivy&amp;ivyXmlPath=ivy.xml&amp;confs=*&amp;ivySettingsPath=&amp;propertyFiles=version.properties"/>
24 <classpathentry kind="output" path="bin"/>
25 </classpath>
0 # Mark the test specific pom files (which have backing checksum files) as binary
1 # so that auto conversion of line endings aren't done on them (thus resulting in
2 # different checksums) during git checkout.
3 test/**/maven-snapshot-test/**/*.pom -text diff
4
0 .classpath
1 .DS_Store
2 .idea
3 *.iml
4 .ivy2
5 *~
6 asciidoc/tutorial/log
7 bin
8 build
9 doc/style/.svn
10 doc/xooki/.svn
11 doc/samples/target-platform/bundles
12 doc/samples/target-platform/cache
13 lib
14 tagsdoc.properties
15 test/jar-repos
16 test/repositories/checkmodified/ivy-1.0.xml
17 test/repositories/checkmodified/mod1.1-1.0.jar
18 test/repositories/norevision/ivy-mod1.1.xml
19 test/repositories/norevision/mod1.1.jar
20 test/test-repo/bundlerepo/*.jar
21 test/test-repo/ivyrepo/org.apache.ivy.osgi
22 out/
(New empty file)
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 https://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18 -->
19 <projectDescription>
20 <name>ivy</name>
21 <comment></comment>
22 <projects>
23 </projects>
24 <buildSpec>
25 <buildCommand>
26 <name>org.eclipse.jdt.core.javabuilder</name>
27 <arguments>
28 </arguments>
29 </buildCommand>
30 <buildCommand>
31 <name>org.eclipse.pde.ManifestBuilder</name>
32 <arguments>
33 </arguments>
34 </buildCommand>
35 <buildCommand>
36 <name>net.sf.eclipsecs.core.CheckstyleBuilder</name>
37 <arguments>
38 </arguments>
39 </buildCommand>
40 </buildSpec>
41 <natures>
42 <nature>org.eclipse.pde.PluginNature</nature>
43 <nature>org.eclipse.jdt.core.javanature</nature>
44 <nature>net.sf.eclipsecs.core.CheckstyleNature</nature>
45 <nature>org.apache.ivyde.eclipse.ivynature</nature>
46 </natures>
47 </projectDescription>
0 #Thu Mar 13 22:45:49 CET 2014
1 # ***************************************************************
2 # * Licensed to the Apache Software Foundation (ASF) under one
3 # * or more contributor license agreements. See the NOTICE file
4 # * distributed with this work for additional information
5 # * regarding copyright ownership. The ASF licenses this file
6 # * to you under the Apache License, Version 2.0 (the
7 # * "License"); you may not use this file except in compliance
8 # * with the License. You may obtain a copy of the License at
9 # *
10 # * https://www.apache.org/licenses/LICENSE-2.0
11 # *
12 # * Unless required by applicable law or agreed to in writing,
13 # * software distributed under the License is distributed on an
14 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 # * KIND, either express or implied. See the License for the
16 # * specific language governing permissions and limitations
17 # * under the License.
18 # ***************************************************************
19 eclipse.preferences.version=1
20 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
21 org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
22 org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
23 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
24 org.eclipse.jdt.core.compiler.compliance=1.7
25 org.eclipse.jdt.core.compiler.debug.lineNumber=generate
26 org.eclipse.jdt.core.compiler.debug.localVariable=generate
27 org.eclipse.jdt.core.compiler.debug.sourceFile=generate
28 org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
29 org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
30 org.eclipse.jdt.core.compiler.source=1.7
31 org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
32 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
33 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
34 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
35 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
36 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=20
37 org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
38 org.eclipse.jdt.core.formatter.alignment_for_assignment=0
39 org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
40 org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
41 org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
42 org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
43 org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
44 org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
45 org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
46 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
47 org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
48 org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
49 org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
50 org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
51 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
52 org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
53 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
54 org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
55 org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
56 org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
57 org.eclipse.jdt.core.formatter.blank_lines_after_package=1
58 org.eclipse.jdt.core.formatter.blank_lines_before_field=1
59 org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
60 org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
61 org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
62 org.eclipse.jdt.core.formatter.blank_lines_before_method=1
63 org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
64 org.eclipse.jdt.core.formatter.blank_lines_before_package=0
65 org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
66 org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
67 org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
68 org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
69 org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
70 org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
71 org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
72 org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
73 org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
74 org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
75 org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
76 org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
77 org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
78 org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
79 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
80 org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
81 org.eclipse.jdt.core.formatter.comment.format_block_comments=true
82 org.eclipse.jdt.core.formatter.comment.format_header=false
83 org.eclipse.jdt.core.formatter.comment.format_html=true
84 org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
85 org.eclipse.jdt.core.formatter.comment.format_line_comments=true
86 org.eclipse.jdt.core.formatter.comment.format_source_code=true
87 org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
88 org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
89 org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
90 org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
91 org.eclipse.jdt.core.formatter.comment.line_length=100
92 org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
93 org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
94 org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
95 org.eclipse.jdt.core.formatter.compact_else_if=true
96 org.eclipse.jdt.core.formatter.continuation_indentation=2
97 org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
98 org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
99 org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
100 org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
101 org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
102 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
103 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
104 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
105 org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
106 org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
107 org.eclipse.jdt.core.formatter.indent_empty_lines=false
108 org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
109 org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
110 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
111 org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=true
112 org.eclipse.jdt.core.formatter.indentation.size=4
113 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
114 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
115 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
116 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
117 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
118 org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
119 org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
120 org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
121 org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
122 org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
123 org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
124 org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
125 org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
126 org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
127 org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
128 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
129 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
130 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
131 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
132 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
133 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
134 org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
135 org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
136 org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
137 org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
138 org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
139 org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
140 org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
141 org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
142 org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
143 org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
144 org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
145 org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
146 org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
147 org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
148 org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
149 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
150 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
151 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
152 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
153 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
154 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
155 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
156 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
157 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
158 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
159 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
160 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
161 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
162 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
163 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
164 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
165 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
166 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
167 org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
168 org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
169 org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
170 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
171 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
172 org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
173 org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=do not insert
174 org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
175 org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
176 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
177 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
178 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
179 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
180 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
181 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
182 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
183 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
184 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
185 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
186 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
187 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
188 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
189 org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
190 org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
191 org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
192 org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
193 org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
194 org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
195 org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
196 org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
197 org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
198 org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
199 org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
200 org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
201 org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
202 org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
203 org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
204 org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=do not insert
205 org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
206 org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
207 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
208 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
209 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
210 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
211 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
212 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
213 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
214 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
215 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
216 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
217 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
218 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
219 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
220 org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
221 org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
222 org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
223 org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
224 org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
225 org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
226 org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
227 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
228 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
229 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
230 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
231 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
232 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
233 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
234 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
235 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
236 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
237 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
238 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
239 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
240 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
241 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
242 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
243 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
244 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
245 org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
246 org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
247 org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
248 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
249 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
250 org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
251 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
252 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
253 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
254 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
255 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
256 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
257 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
258 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
259 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
260 org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
261 org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
262 org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
263 org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
264 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
265 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
266 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
267 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
268 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
269 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
270 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
271 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
272 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
273 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
274 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
275 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
276 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
277 org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
278 org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
279 org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
280 org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
281 org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
282 org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
283 org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
284 org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
285 org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
286 org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
287 org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
288 org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
289 org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
290 org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
291 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
292 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
293 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
294 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
295 org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
296 org.eclipse.jdt.core.formatter.join_lines_in_comments=true
297 org.eclipse.jdt.core.formatter.join_wrapped_lines=true
298 org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
299 org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
300 org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
301 org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
302 org.eclipse.jdt.core.formatter.lineSplit=100
303 org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
304 org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
305 org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
306 org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
307 org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
308 org.eclipse.jdt.core.formatter.tabulation.char=space
309 org.eclipse.jdt.core.formatter.tabulation.size=4
310 org.eclipse.jdt.core.formatter.use_on_off_tags=false
311 org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
312 org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
313 org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
314 org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
315 org.eclipse.jdt.core.javaFormatter=org.eclipse.jdt.core.defaultJavaFormatter
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
18 eclipse.preferences.version=1
19 editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
20 formatter_profile=_Ivy Conventions
21 formatter_settings_version=12
22 internal.default.compliance=default
23 org.eclipse.jdt.ui.javadoc=false
24 org.eclipse.jdt.ui.text.custom_code_templates=<?xml version\="1.0" encoding\="UTF-8" standalone\="no"?><templates><template autoinsert\="true" context\="gettercomment_context" deleted\="false" description\="Comment for getter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.gettercomment" name\="gettercomment">/**\n * @return the ${bare_field_name}\n */</template><template autoinsert\="true" context\="settercomment_context" deleted\="false" description\="Comment for setter method" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.settercomment" name\="settercomment">/**\n * @param ${param} the ${bare_field_name} to set\n */</template><template autoinsert\="true" context\="constructorcomment_context" deleted\="false" description\="Comment for created constructors" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorcomment" name\="constructorcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="filecomment_context" deleted\="false" description\="Comment for created Java files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.filecomment" name\="filecomment">/**\n * \n */</template><template autoinsert\="true" context\="typecomment_context" deleted\="false" description\="Comment for created types" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.typecomment" name\="typecomment">/**\n * @author ${user}\n *\n * ${tags}\n */</template><template autoinsert\="true" context\="fieldcomment_context" deleted\="false" description\="Comment for fields" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.fieldcomment" name\="fieldcomment">/**\n * \n */</template><template autoinsert\="true" context\="methodcomment_context" deleted\="false" description\="Comment for non-overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodcomment" name\="methodcomment">/**\n * ${tags}\n */</template><template autoinsert\="true" context\="overridecomment_context" deleted\="false" description\="Comment for overriding methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.overridecomment" name\="overridecomment">/* (non-Javadoc)\n * ${see_to_overridden}\n */</template><template autoinsert\="true" context\="delegatecomment_context" deleted\="false" description\="Comment for delegate methods" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.delegatecomment" name\="delegatecomment">/**\n * ${tags}\n * ${see_to_target}\n */</template><template autoinsert\="false" context\="newtype_context" deleted\="false" description\="Newly created files" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.newtype" name\="newtype">/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the "License"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http\://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n${package_declaration}\n\n${typecomment}\n${type_declaration}</template><template autoinsert\="true" context\="classbody_context" deleted\="false" description\="Code in new class type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.classbody" name\="classbody">\n</template><template autoinsert\="true" context\="interfacebody_context" deleted\="false" description\="Code in new interface type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.interfacebody" name\="interfacebody">\n</template><template autoinsert\="true" context\="enumbody_context" deleted\="false" description\="Code in new enum type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.enumbody" name\="enumbody">\n</template><template autoinsert\="true" context\="annotationbody_context" deleted\="false" description\="Code in new annotation type bodies" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.annotationbody" name\="annotationbody">\n</template><template autoinsert\="true" context\="catchblock_context" deleted\="false" description\="Code in new catch blocks" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.catchblock" name\="catchblock">// ${todo} Auto-generated catch block\n${exception_var}.printStackTrace();</template><template autoinsert\="true" context\="methodbody_context" deleted\="false" description\="Code in created method stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.methodbody" name\="methodbody">// ${todo} Auto-generated method stub\n${body_statement}</template><template autoinsert\="true" context\="constructorbody_context" deleted\="false" description\="Code in created constructor stubs" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.constructorbody" name\="constructorbody">${body_statement}\n// ${todo} Auto-generated constructor stub</template><template autoinsert\="true" context\="getterbody_context" deleted\="false" description\="Code in created getters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.getterbody" name\="getterbody">return ${field};</template><template autoinsert\="true" context\="setterbody_context" deleted\="false" description\="Code in created setters" enabled\="true" id\="org.eclipse.jdt.ui.text.codetemplates.setterbody" name\="setterbody">${field} \= ${param};</template></templates>
25 sp_cleanup.add_default_serial_version_id=true
26 sp_cleanup.add_generated_serial_version_id=false
27 sp_cleanup.add_missing_annotations=true
28 sp_cleanup.add_missing_deprecated_annotations=true
29 sp_cleanup.add_missing_methods=false
30 sp_cleanup.add_missing_nls_tags=false
31 sp_cleanup.add_missing_override_annotations=true
32 sp_cleanup.add_missing_override_annotations_interface_methods=true
33 sp_cleanup.add_serial_version_id=false
34 sp_cleanup.always_use_blocks=true
35 sp_cleanup.always_use_parentheses_in_expressions=false
36 sp_cleanup.always_use_this_for_non_static_field_access=false
37 sp_cleanup.always_use_this_for_non_static_method_access=false
38 sp_cleanup.convert_functional_interfaces=false
39 sp_cleanup.convert_to_enhanced_for_loop=false
40 sp_cleanup.correct_indentation=false
41 sp_cleanup.format_source_code=true
42 sp_cleanup.format_source_code_changes_only=false
43 sp_cleanup.insert_inferred_type_arguments=false
44 sp_cleanup.make_local_variable_final=false
45 sp_cleanup.make_parameters_final=false
46 sp_cleanup.make_private_fields_final=true
47 sp_cleanup.make_type_abstract_if_missing_method=false
48 sp_cleanup.make_variable_declarations_final=true
49 sp_cleanup.never_use_blocks=false
50 sp_cleanup.never_use_parentheses_in_expressions=true
51 sp_cleanup.on_save_use_additional_actions=false
52 sp_cleanup.organize_imports=true
53 sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
54 sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
55 sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
56 sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
57 sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
58 sp_cleanup.remove_private_constructors=true
59 sp_cleanup.remove_redundant_type_arguments=false
60 sp_cleanup.remove_trailing_whitespaces=false
61 sp_cleanup.remove_trailing_whitespaces_all=true
62 sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
63 sp_cleanup.remove_unnecessary_casts=true
64 sp_cleanup.remove_unnecessary_nls_tags=false
65 sp_cleanup.remove_unused_imports=false
66 sp_cleanup.remove_unused_local_variables=false
67 sp_cleanup.remove_unused_private_fields=true
68 sp_cleanup.remove_unused_private_members=false
69 sp_cleanup.remove_unused_private_methods=true
70 sp_cleanup.remove_unused_private_types=true
71 sp_cleanup.sort_members=false
72 sp_cleanup.sort_members_all=false
73 sp_cleanup.use_anonymous_class_creation=false
74 sp_cleanup.use_blocks=false
75 sp_cleanup.use_blocks_only_for_return_and_throw=false
76 sp_cleanup.use_lambda=false
77 sp_cleanup.use_parentheses_in_expressions=false
78 sp_cleanup.use_this_for_non_static_field_access=false
79 sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
80 sp_cleanup.use_this_for_non_static_method_access=false
81 sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
82 sp_cleanup.use_type_arguments=false
0 #Sun Sep 03 16:43:34 PDT 2006
1 # ***************************************************************
2 # * Licensed to the Apache Software Foundation (ASF) under one
3 # * or more contributor license agreements. See the NOTICE file
4 # * distributed with this work for additional information
5 # * regarding copyright ownership. The ASF licenses this file
6 # * to you under the Apache License, Version 2.0 (the
7 # * "License"); you may not use this file except in compliance
8 # * with the License. You may obtain a copy of the License at
9 # *
10 # * https://www.apache.org/licenses/LICENSE-2.0
11 # *
12 # * Unless required by applicable law or agreed to in writing,
13 # * software distributed under the License is distributed on an
14 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 # * KIND, either express or implied. See the License for the
16 # * specific language governing permissions and limitations
17 # * under the License.
18 # ***************************************************************
19 acceptedTypes=[inherited]
20 eclipse.preferences.version=1
21 ivy_conf_path=file\:///./ivysettings.xml
22 retreive.pattern=none
191191 you may not use this file except in compliance with the License.
192192 You may obtain a copy of the License at
193193
194 http://www.apache.org/licenses/LICENSE-2.0
194 https://www.apache.org/licenses/LICENSE-2.0
195195
196196 Unless required by applicable law or agreed to in writing, software
197197 distributed under the License is distributed on an "AS IS" BASIS,
254254 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
255255 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
256256 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
257
257
258 ------------------------------------------------------------------------------
259 License for ganymed ssh library
260 ------------------------------------------------------------------------------
261
262 Copyright (c) 2005 - 2006 Swiss Federal Institute of Technology (ETH Zurich),
263 Department of Computer Science (http://www.inf.ethz.ch),
264 Christian Plattner. All rights reserved.
265
266 Redistribution and use in source and binary forms, with or without
267 modification, are permitted provided that the following conditions
268 are met:
269
270 a.) Redistributions of source code must retain the above copyright
271 notice, this list of conditions and the following disclaimer.
272 b.) Redistributions in binary form must reproduce the above copyright
273 notice, this list of conditions and the following disclaimer in the
274 documentation and/or other materials provided with the distribution.
275 c.) Neither the name of ETH Zurich nor the names of its contributors may
276 be used to endorse or promote products derived from this software
277 without specific prior written permission.
278
279 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
280 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
281 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
282 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
283 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
284 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
285 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
286 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
287 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
288 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
289 POSSIBILITY OF SUCH DAMAGE
00 Manifest-Version: 1.0
11 Main-Class: org.apache.ivy.Main
2 Automatic-Module-Name: org.apache.ivy
23 Bundle-Version: 2.4.0
34 Bundle-Name: Ivy
45 Bundle-ManifestVersion: 2
56 Bundle-SymbolicName: org.apache.ivy
67 Bundle-Vendor: Apache Software Foundation
7 Bundle-DocURL: http://ant.apache.org/ivy/
8 Bundle-DocURL: https://ant.apache.org/ivy/
89 Import-Package: com.jcraft.jsch;resolution:=optional,
910 javax.crypto;resolution:=optional,
1011 javax.swing;resolution:=optional,
1920 org.apache.commons.httpclient.params;resolution:=optional,
2021 org.apache.commons.httpclient.protocol;resolution:=optional,
2122 org.apache.commons.net.ftp;resolution:=optional,
22 org.apache.commons.vfs;resolution:=optional,
23 org.apache.commons.vfs.impl;resolution:=optional,
24 org.apache.commons.vfs.provider;resolution:=optional,
25 org.apache.commons.vfs.provider.ftp;resolution:=optional,
26 org.apache.commons.vfs.provider.local;resolution:=optional,
27 org.apache.commons.vfs.provider.sftp;resolution:=optional,
28 org.apache.commons.vfs.provider.url;resolution:=optional,
23 org.apache.commons.vfs2;resolution:=optional,
24 org.apache.commons.vfs2.impl;resolution:=optional,
25 org.apache.commons.vfs2.provider;resolution:=optional,
26 org.apache.commons.vfs2.provider.ftp;resolution:=optional,
27 org.apache.commons.vfs2.provider.local;resolution:=optional,
28 org.apache.commons.vfs2.provider.sftp;resolution:=optional,
29 org.apache.commons.vfs2.provider.url;resolution:=optional,
2930 org.apache.oro.text;resolution:=optional,
3031 org.apache.oro.text.regex;resolution:=optional,
3132 org.apache.tools.ant;resolution:=optional,
108109 org.apache.ivy.util.filter;version="2.0.0",
109110 org.apache.ivy.util.url;version="2.0.0"
110111 Bundle-ClassPath: .
111 Bundle-RequiredExecutionEnvironment: J2SE-1.5
112 Bundle-RequiredExecutionEnvironment: JavaSE-1.7
00 Apache Ivy (TM)
1 Copyright 2007-2014 The Apache Software Foundation
1 Copyright 2007-2019 The Apache Software Foundation
22
33 This product includes software developed at
44 The Apache Software Foundation (http://www.apache.org/).
1313 the terms of a BSD style license.
1414 The original software and related information is available
1515 at http://www.jcraft.com/jsch/.
16
17 The Scp class is based on the SCPClient from the ganymed ssh
18 library. Which has been distributed under the BSD style license
19 included in the LICENSE file.
+0
-95
README less more
0 Apache Ivy (TM)
1 -----------------------------------------------------------------------
2
3
4 What is Apache Ivy?
5 --------------------
6
7 Apache Ivy is a tool for managing (recording, tracking, resolving and reporting)
8 project dependencies.
9 It is characterized by the following:
10
11 1. flexibility and configurability
12 Apache Ivy is essentially process agnostic and is not tied to any
13 methodology or structure.
14 Instead it provides the necessary flexibility and configurability
15 to be adapted to a broad range of dependency management and build
16 processes.
17 2. tight integration with Apache Ant
18 while available as a standalone tool, Apache Ivy works particularly well
19 with Apache Ant providing a number of powerful Ant tasks ranging
20 from dependency resolution to dependency reporting and publication.
21
22
23 Latest Changes:
24 ----------------
25
26 See the list of the changes since the last release in the file doc/release-notes.html
27
28
29 Supported Platforms
30 --------------------
31
32 Please see the the detailed documentation about Ivy compatibility there: doc/compatibility.html
33
34
35 Installation
36 -------------
37
38 Please read doc/install.html for installation instructions.
39
40
41 Licensing
42 ---------
43
44 This software is licensed under the terms you may find in the file
45 named "LICENSE" in this directory.
46
47
48 Crypto Notice
49 -------------
50 This distribution includes cryptographic software. The country in
51 which you currently reside may have restrictions on the import,
52 possession, use, and/or re-export to another country, of
53 encryption software. BEFORE using any encryption software, please
54 check your country's laws, regulations and policies concerning the
55 import, possession, or use, and re-export of encryption software, to
56 see if this is permitted. See <http://www.wassenaar.org/> for more
57 information.
58
59 The U.S. Government Department of Commerce, Bureau of Industry and
60 Security (BIS), has classified this software as Export Commodity
61 Control Number (ECCN) 5D002.C.1, which includes information security
62 software using or performing cryptographic functions with asymmetric
63 algorithms. The form and manner of this Apache Software Foundation
64 distribution makes it eligible for export under the License Exception
65 ENC Technology Software Unrestricted (TSU) exception (see the BIS
66 Export Administration Regulations, Section 740.13) for both object
67 code and source code.
68
69 The following provides more details on the included cryptographic
70 software:
71
72 The Ivy ssh resolver requires the JSch library
73 <http://www.jcraft.com/jsch/index.html>.
74 The sftp and https resolvers requires the Java Cryptography extensions
75 <http://java.sun.com/javase/technologies/security/>.
76 The PGP signature generator requires the BouncyCastle Java cryptography APIs
77 <http://www.bouncycastle.org/java.html>.
78
79
80 How to Get Involved
81 --------------------
82
83 The Apache Ivy project really needs and appreciates any contributions,
84 including documentation help, source code and feedback. If you are interested
85 in contributing, please visit http://ant.apache.org/ivy/get-involved.html.
86
87
88 How to Report Issues
89 --------------------
90
91 The Apache Ivy project uses JIRA for issue tracking. Please report any
92 issues you find at http://issues.apache.org/jira/browse/IVY
93
94
0 ////
1 Licensed to the Apache Software Foundation (ASF) under one
2 or more contributor license agreements. See the NOTICE file
3 distributed with this work for additional information
4 regarding copyright ownership. The ASF licenses this file
5 to you under the Apache License, Version 2.0 (the
6 "License"); you may not use this file except in compliance
7 with the License. You may obtain a copy of the License at
8
9 https://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing,
12 software distributed under the License is distributed on an
13 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 KIND, either express or implied. See the License for the
15 specific language governing permissions and limitations
16 under the License.
17 ////
18
19 = Apache Ivy(TM)
20
21
22 == What is Apache Ivy?
23
24 Apache Ivy is a tool for managing (recording, tracking, resolving and reporting)
25 project dependencies.
26 It is characterized by the following:
27
28 1. flexibility and configurability
29 +
30 Apache Ivy is essentially process agnostic and is not tied to any
31 methodology or structure.
32 Instead it provides the necessary flexibility and configurability
33 to be adapted to a broad range of dependency management and build
34 processes.
35
36 2. tight integration with Apache Ant
37 +
38 While available as a standalone tool, Apache Ivy works particularly well
39 with Apache Ant providing a number of powerful Ant tasks ranging
40 from dependency resolution to dependency reporting and publication.
41
42 == Latest Changes:
43
44 See the list of the changes since the last release in the file
45 link:asciidoc/release-notes{outfilesuffix}[asciidoc/release-notes.adoc]
46
47 == Supported Platforms
48
49 Please see the the detailed documentation about Ivy compatibility here:
50 link:asciidoc/compatibility{outfilesuffix}[asciidoc/compatibility.adoc]
51
52 == Installation
53
54 Please read link:asciidoc/install{outfilesuffix}[asciidoc/install.adoc]
55 for installation instructions.
56
57 == Licensing
58
59 This software is licensed under the terms you may find in the file
60 named link:LICENSE["LICENSE"] in this directory.
61
62 == Crypto Notice
63
64 This distribution includes cryptographic software. The country in
65 which you currently reside may have restrictions on the import,
66 possession, use, and/or re-export to another country, of
67 encryption software. BEFORE using any encryption software, please
68 check your country's laws, regulations and policies concerning the
69 import, possession, or use, and re-export of encryption software, to
70 see if this is permitted. See https://www.wassenaar.org/ for more
71 information.
72
73 The U.S. Government Department of Commerce, Bureau of Industry and
74 Security (BIS), has classified this software as Export Commodity
75 Control Number (ECCN) 5D002.C.1, which includes information security
76 software using or performing cryptographic functions with asymmetric
77 algorithms. The form and manner of this Apache Software Foundation
78 distribution makes it eligible for export under the License Exception
79 ENC Technology Software Unrestricted (TSU) exception (see the BIS
80 Export Administration Regulations, Section 740.13) for both object
81 code and source code.
82
83 The following provides more details on the included cryptographic
84 software:
85
86 The Ivy ssh resolver requires the JSch library
87 http://www.jcraft.com/jsch/index.html. +
88 The sftp and https resolvers requires the Java Cryptography extensions
89 https://java.sun.com/javase/technologies/security/. +
90 The PGP signature generator requires the BouncyCastle Java cryptography APIs
91 https://www.bouncycastle.org/java.html.
92
93 == How to Get Involved
94
95 The Apache Ivy project really needs and appreciates any contributions,
96 including documentation help, source code and feedback. If you are interested
97 in contributing, please visit https://ant.apache.org/ivy/get-involved.html.
98
99 == How to Report Issues
100
101 The Apache Ivy project uses JIRA for issue tracking. Please report any
102 issues you find at https://issues.apache.org/jira/browse/IVY
103
104
0 Release instructions are in asciidoc/dev/makerelease.adoc
1
2 You can see the last version online here: https://ant.apache.org/ivy/history/master/dev/makerelease.html
66 # * "License"); you may not use this file except in compliance
77 # * with the License. You may obtain a copy of the License at
88 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
9 # * https://www.apache.org/licenses/LICENSE-2.0
1010 # *
1111 # * Unless required by applicable law or agreed to in writing,
1212 # * software distributed under the License is distributed on an
0 <!--
1 Licensed to the Apache Software Foundation (ASF) under one
2 or more contributor license agreements. See the NOTICE file
3 distributed with this work for additional information
4 regarding copyright ownership. The ASF licenses this file
5 to you under the Apache License, Version 2.0 (the
6 "License"); you may not use this file except in compliance
7 with the License. You may obtain a copy of the License at
8
9 https://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing,
12 software distributed under the License is distributed on an
13 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 KIND, either express or implied. See the License for the
15 specific language governing permissions and limitations
16 under the License.
17 -->
18 <project name="retrieve-ivy-deps" default="retrieve-all"
19 xmlns:ivy="antlib:org.apache.ivy.ant">
20
21 <target name="init-ivy">
22 <taskdef resource="org/apache/ivy/ant/antlib.xml"
23 uri="antlib:org.apache.ivy.ant"
24 classpath="ivy.jar"/>
25 </target>
26
27 <target name="report">
28 <ivy:report graph="false" todir="report"/>
29 <echo>
30 =======================================================================
31 Dependencies retrieved in lib directory
32 Dependency report generated in report directory
33 =======================================================================
34 </echo>
35 </target>
36
37 <target name="retrieve-conf" depends="init-ivy"
38 description="--> Retrieves a set of configuration (get only dependencies needed).">
39 <ivy:info file="ivy.xml"/>
40 <echo>
41 =======================================================================
42 Please enter configuration (or comma separated list of configurations).
43 Available configurations are: ${ivy.configurations}</echo>
44 <input message="Configuration(s):" addproperty="ivy.confs"/>
45 <ivy:retrieve conf="${ivy.confs}"/>
46 <antcall target="report" inheritRefs="true"/>
47 </target>
48
49 <target name="retrieve-all" depends="init-ivy"
50 description="--> Retrieves all Ivy dependencies into the lib directory">
51 <ivy:retrieve/>
52 <antcall target="report" inheritRefs="true"/>
53 </target>
54 </project>
0 <!--
1 Licensed to the Apache Software Foundation (ASF) under one
2 or more contributor license agreements. See the NOTICE file
3 distributed with this work for additional information
4 regarding copyright ownership. The ASF licenses this file
5 to you under the Apache License, Version 2.0 (the
6 "License"); you may not use this file except in compliance
7 with the License. You may obtain a copy of the License at
8
9 https://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing,
12 software distributed under the License is distributed on an
13 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 KIND, either express or implied. See the License for the
15 specific language governing permissions and limitations
16 under the License.
17 -->
18 <project name="IvyRelease" default="snapshot"
19 xmlns:ivy="antlib:org.apache.ivy.ant"
20 xmlns:ivy2="antlib:org.apache.ivy.ant_2"
21 xmlns:asciidoctor="antlib:org.asciidoctor.ant"
22 xmlns:openpgp="antlib:org.apache.commons.openpgp.ant">
23
24 <import file="build.xml"/>
25
26 <macrodef name="run-tutorial">
27 <attribute name="antfile"/>
28 <attribute name="output"/>
29 <attribute name="target" default=""/>
30 <attribute name="failonerror" default="true"/>
31 <sequential>
32 <echo>Running @{antfile} @{target} > @{output}</echo>
33
34 <local name="antfile.dir"/>
35 <dirname property="antfile.dir" file="@{antfile}"/>
36
37 <local name="antfile.name"/>
38 <basename property="antfile.name" file="@{antfile}"/>
39
40 <echo file="@{output}">[ivy@apache:${antfile.dir}]$ ant -f ${antfile.name} @{target}${line.separator}</echo>
41 <java classname="org.apache.tools.ant.launch.Launcher"
42 fork="true"
43 failonerror="@{failonerror}"
44 logerror="true"
45 append="true"
46 output="@{output}">
47 <classpath>
48 <fileset file="${artifacts.build.dir}/jars/${final.name}"/>
49
50 <!--
51 We need to set the classpath like this, otherwise the invoked
52 build scripts are not capable of compiling sources ???
53 -->
54 <path path="${java.class.path}"/>
55 </classpath>
56 <sysproperty key="ivy.cache.dir" value="${tutorial.cache}"/>
57 <sysproperty key="ivy.local.default.root" value="${tutorial.local-repo}"/>
58 <sysproperty key="ivy.cache.ttl.default" value="1s"/>
59 <sysproperty key="skip.download" value="true"/>
60 <!-- We select specific HTTPS protocols, based on the Java version we are running
61 on -->
62 <sysproperty key="https.protocols" value="${java.sysprop.https.protocols}"/>
63 <arg line="-f @{antfile}"/>
64 <arg line="@{target}"/>
65 </java>
66 </sequential>
67 </macrodef>
68
69 <target name="generate-tutorial-output" depends="jar" unless="skip.generate-tutorial-output">
70 <property name="output.dir" value="${basedir}/asciidoc/tutorial/log"/>
71 <delete dir="${output.dir}"/>
72 <mkdir dir="${output.dir}"/>
73
74 <!-- create a copy of the tutorials so we can easily get rid of the generated files -->
75 <property name="tutorial.src.dir" value="${build.dir}/examples"/>
76 <delete dir="${tutorial.src.dir}"/>
77 <mkdir dir="${tutorial.src.dir}"/>
78 <copy todir="${tutorial.src.dir}">
79 <fileset dir="src/example"/>
80 </copy>
81
82 <!-- create a cache and local-repository for the tutorials -->
83 <property name="tutorial.build.dir" value="${build.dir}/tutorial"/>
84 <property name="tutorial.cache" value="${tutorial.build.dir}/cache"/>
85 <property name="tutorial.local-repo" value="${tutorial.build.dir}/local"/>
86
87 <!-- go-ivy : not logged, but run in order to check if it still run -->
88 <run-tutorial antfile="${tutorial.src.dir}/go-ivy/build.xml" output="${output.dir}/dummy.txt"/>
89 <delete file="${output.dir}/dummy.txt"/>
90 <delete dir="${tutorial.build.dir}"/>
91
92 <!-- hello-ivy : Quick Start - start.html -->
93 <run-tutorial antfile="${tutorial.src.dir}/hello-ivy/build.xml" output="${output.dir}/hello-ivy-1.txt"/>
94 <run-tutorial antfile="${tutorial.src.dir}/hello-ivy/build.xml" output="${output.dir}/hello-ivy-2.txt"/>
95 <delete dir="${tutorial.build.dir}"/>
96
97 <!-- multiple resolvers - multiple.html -->
98 <run-tutorial antfile="${tutorial.src.dir}/chained-resolvers/chainedresolvers-project/build.xml" output="${output.dir}/chained-resolvers.txt"/>
99 <delete dir="${tutorial.build.dir}"/>
100
101 <!-- dual - dual.html -->
102 <run-tutorial antfile="${tutorial.src.dir}/dual/project/build.xml" output="${output.dir}/dual.txt"/>
103 <delete dir="${tutorial.build.dir}"/>
104
105 <!-- Project dependencies - multi-project.html -->
106 <run-tutorial antfile="${tutorial.src.dir}/dependence/dependee/build.xml" target="publish" output="${output.dir}/dependence-standalone.txt"/>
107 <run-tutorial antfile="${tutorial.src.dir}/dependence/depender/build.xml" output="${output.dir}/dependence-depending.txt"/>
108 <run-tutorial antfile="${tutorial.src.dir}/dependence/dependee/build.xml" target="publish" output="${output.dir}/dependence-standalone-2.txt"/>
109 <run-tutorial antfile="${tutorial.src.dir}/dependence/depender/build.xml" output="${output.dir}/dependence-depending-2.txt"/>
110 <delete dir="${tutorial.build.dir}"/>
111
112 <!-- configuration - Using Ivy Configuration - conf.html -->
113 <run-tutorial antfile="${tutorial.src.dir}/configurations/multi-projects/filter-framework/build.xml" output="${output.dir}/configurations-lib.txt"/>
114 <run-tutorial antfile="${tutorial.src.dir}/configurations/multi-projects/myapp/build.xml" output="${output.dir}/configurations-runcc.txt"/>
115 <run-tutorial antfile="${tutorial.src.dir}/configurations/multi-projects/myapp/build.xml" target="run-hm" output="${output.dir}/configurations-runhm.txt"/>
116 <delete dir="${tutorial.build.dir}"/>
117
118 <!--Building a repository - basic.html -->
119 <run-tutorial antfile="${tutorial.src.dir}/build-a-ivy-repository/build.xml" target="maven2" output="${output.dir}/install.txt"/>
120 <pathconvert property="myrepository.content" pathsep="${line.separator}">
121 <fileset dir="${tutorial.src.dir}/build-a-ivy-repository/myrepository/no-namespace"/>
122 </pathconvert>
123 <echo file="${output.dir}/myrepository-content.txt">[ivy@apache:/]$ find ${tutorial.src.dir}/build-a-ivy-repository/myrepository/no-namespace -type f -print${line.separator}</echo>
124 <echo file="${output.dir}/myrepository-content.txt" append="true">${myrepository.content}</echo>
125 <delete dir="${tutorial.build.dir}"/>
126 <echo>NB! This tutorial fails deliberately!</echo>
127 <run-tutorial antfile="${tutorial.src.dir}/build-a-ivy-repository/build.xml" target="maven2-deps" output="${output.dir}/install-deps.txt" failonerror="false"/>
128 <pathconvert property="myrepository.content.deps" pathsep="${line.separator}">
129 <fileset dir="${tutorial.src.dir}/build-a-ivy-repository/myrepository/no-namespace/org.hibernate/hibernate"/>
130 </pathconvert>
131 <echo file="${output.dir}/myrepository-content-deps.txt">[ivy@apache:/]$ find ${tutorial.src.dir}/build-a-ivy-repository/myrepository/no-namespace/org.hibernate/hibernate -type f -print${line.separator}</echo>
132 <echo file="${output.dir}/myrepository-content-deps.txt" append="true">${myrepository.content.deps}</echo>
133 <delete dir="${tutorial.build.dir}"/>
134
135 <!--Building a repository - advanced.html -->
136 <run-tutorial antfile="${tutorial.src.dir}/build-a-ivy-repository/build.xml" target="maven2-namespace" output="${output.dir}/install-namespace.txt"/>
137 <pathconvert property="myrepository.content.namespace" pathsep="${line.separator}">
138 <fileset dir="${tutorial.src.dir}/build-a-ivy-repository/myrepository/advanced"/>
139 </pathconvert>
140 <echo file="${output.dir}/myrepository-content-namespace.txt">$ find ${tutorial.src.dir}/build-a-ivy-repository/myrepository/advanced -type f -print${line.separator}</echo>
141 <echo file="${output.dir}/myrepository-content-namespace.txt" append="true">${myrepository.content.namespace}</echo>
142 <delete dir="${tutorial.build.dir}"/>
143
144 <!-- multi-project - multiproject.html -->
145 <run-tutorial antfile="${tutorial.src.dir}/multi-project/build.xml" target="-p" output="${output.dir}/multi-project-general-antp.txt"/>
146 <run-tutorial antfile="${tutorial.src.dir}/multi-project/projects/find/build.xml" target="-p" output="${output.dir}/multi-project-find-antp.txt"/>
147 <run-tutorial antfile="${tutorial.src.dir}/multi-project/build.xml" target="publish-all" output="${output.dir}/multi-project-general-publishall.txt"/>
148 <delete dir="${tutorial.build.dir}"/>
149
150 <!-- Correct the location of the examples to a dummy '/ivy' location -->
151 <pathconvert property="tutorial.root" dirsep="/">
152 <identitymapper/>
153 <path location="${tutorial.src.dir}"/>
154 </pathconvert>
155 <pathconvert property="tutorial.local" dirsep="/">
156 <identitymapper/>
157 <path location="${tutorial.local-repo}"/>
158 </pathconvert>
159 <pathconvert property="ivy.jar.location" dirsep="/">
160 <identitymapper/>
161 <fileset file="${artifacts.build.dir}/jars/${final.name}"/>
162 </pathconvert>
163
164 <replace dir="${output.dir}" token="\" value="/"/>
165 <replace dir="${output.dir}" token="${tutorial.root}" value="/ivy"/>
166 <replace dir="${output.dir}" token="${tutorial.local}" value="/home/ivy/.ivy2/local"/>
167 <replace dir="${output.dir}" token="${ivy.jar.location}" value="//home/ivy/ivy.jar"/>
168 <replace dir="${output.dir}" token="-f build.xml " value=""/>
169 <replace dir="${output.dir}" token="${ivy.revision}" value="working@apache"/>
170 </target>
171
172 <target name="init-asciidoctor-extensions" depends="init-ivy" unless="skip.doc">
173 <ivy:cachepath pathid="asciidoctorj.path" organisation="org.asciidoctor" module="asciidoctorj" revision="1.5.7" conf="default" inline="true"/>
174 <mkdir dir="${build.dir}/asciidoc-extensions/classes"/>
175 <javac srcdir="${doc.src.dir}/templates/extensions/src" destdir="${build.dir}/asciidoc-extensions/classes"
176 debug="true" includeantruntime="no" classpathref="asciidoctorj.path"/>
177 <copy todir="${build.dir}/asciidoc-extensions">
178 <fileset dir="${doc.src.dir}/templates/extensions/src">
179 <exclude name="**/*.java"/>
180 </fileset>
181 </copy>
182 </target>
183
184 <target name="init-asciidoctor" depends="init-asciidoctor-extensions" unless="skip.doc">
185 <mkdir dir="${build.dir}/asciidoc-lib/jars"/>
186 <mkdir dir="${build.dir}/asciidoc-lib/classes"/>
187 <ivy:retrieve organisation="org.asciidoctor" module="asciidoctor-ant" revision="1.5.5" conf="default" inline="true" pattern="${build.dir}/asciidoc-lib/jars/[artifact].[ext]"/>
188 <unzip src="${build.dir}/asciidoc-lib/jars/asciidoctor-ant.jar" dest="${build.dir}/asciidoc-lib/classes"/>
189 <taskdef uri="antlib:org.asciidoctor.ant" resource="org/asciidoctor/ant/antlib.xml">
190 <classpath>
191 <pathelement location="${build.dir}/asciidoc-extensions/classes"/>
192 <pathelement location="${build.dir}/asciidoc-lib/classes"/>
193 </classpath>
194 </taskdef>
195 </target>
196
197 <target name="copy-doc-files" unless="skip.doc">
198 <copy todir="${doc.build.dir}">
199 <fileset dir="${doc.src.dir}" includes="images/**,style/**,samples/**,js/**,ivy.xsd"/>
200 <fileset dir="${doc.src.dir}" includes="tutorial/log/multi-project-general-publishall.txt"/>
201 </copy>
202 </target>
203
204 <target name="generate-doc" depends="generate-tutorial-output,default-version,init-asciidoctor,copy-doc-files" unless="skip.doc">
205 <asciidoctor:convert sourceDirectory="${doc.src.dir}" outputDirectory="${doc.build.dir}" backend="xhtml5"
206 templateDir="${doc.src.dir}/templates" preserveDirectories="true"
207 sourceHighlighter="highlightjs">
208 <attribute key="basedir" value="${doc.src.dir}"/>
209 <attribute key="imagesdir" value=""/>
210 <attribute key="version" value="${build.version}"/>
211 <inlineMacroProcessor blockName="jira" className="org.apache.ivy.asciidoc.JiraMacro"/>
212 </asciidoctor:convert>
213 </target>
214
215 <target name="generate-book-adoc" depends="default-version,copy-doc-files" unless="skip.doc">
216 <scriptdef name="generate-book-adoc" language="javascript">
217 <attribute name="jsontocfile"/>
218 <attribute name="destFile"/>
219 <![CDATA[
220 var tocfile = self.getProject().resolveFile(attributes.get("jsontocfile"))
221 r = new java.io.BufferedReader(new java.io.FileReader(tocfile));
222 var val = "";
223 while ((s = r.readLine()) != null) {
224 val += s;
225 }
226 r.close();
227 var toc = eval("("+val+")")
228
229 var writeToc = function(o, children, level) {
230 for (var c in children) {
231 o.write(level + ' link:#' + children[c].id.replace(/\//g, '_') + '[' + children[c].title + ']\n');
232 if (children[c].children && children[c].children.length && children[c].children.length != 0) {
233 writeToc(o, children[c].children, level+'*');
234 }
235 }
236 };
237
238 var writeInclude = function(o, children) {
239 for (var c in children) {
240 o.write('== [[' + children[c].id.replace(/\//g, '_') + ']]' + children[c].title + '\n\n');
241 o.write('include::../asciidoc/' + children[c].id + '.adoc[]\n\n');
242 if (children[c].children && children[c].children.length && children[c].children.length != 0) {
243 writeInclude(o, children[c].children);
244 }
245 }
246 };
247
248 out = new java.io.FileWriter(self.getProject().resolveFile(attributes.get("destfile")));
249 out.write('== Table of Contents\n\n');
250 writeToc(out, toc.children[0].children, '*');
251 out.write('\n\n');
252 writeInclude(out, toc.children[0].children, '*');
253 out.close();
254 ]]>
255 </scriptdef>
256 <mkdir dir="${build.dir}/book"/>
257 <generate-book-adoc jsontocfile="${doc.src.dir}/toc.json" destFile="${build.dir}/book/book.adoc"/>
258 </target>
259
260 <target name="generate-book" depends="generate-book-adoc,init-asciidoctor">
261 <asciidoctor:convert sourceDirectory="${build.dir}/book" outputDirectory="${doc.build.dir}" backend="xhtml5"
262 templateDir="${doc.src.dir}/templates/book" sourceHighlighter="highlightjs" doctype="book">
263 <attribute key="version" value="${build.version}"/>
264 <inlineMacroProcessor blockName="jira" className="org.apache.ivy.asciidoc.JiraMacro"/>
265 </asciidoctor:convert>
266 </target>
267
268 <target name="all-doc" depends="javadoc,generate-doc,generate-book"/>
269
270 <target name="init-snapshot" depends="default-version">
271 <property name="snapshot.full.name" value="apache-ivy-${build.version}"/>
272 </target>
273
274 <target name="snapshot-metadata" depends="init-snapshot,resolve">
275 <mkdir dir="${artifacts.build.dir}"/>
276 <ivy:deliver
277 deliverpattern="${artifacts.build.dir}/ivy.xml"
278 pubrevision="${build.version}"
279 pubdate="${pubdate}"
280 status="${status}"/>
281 </target>
282
283 <target name="snapshot-src" depends="init-snapshot">
284 <delete dir="${build.dir}/snapshot-src" failonerror="false"/>
285 <exec executable="git" failonerror="true">
286 <arg line="clone ${basedir} ${build.dir}/snapshot-src"/>
287 </exec>
288 <exec dir="${build.dir}/snapshot-src" executable="git" failonerror="true">
289 <arg line="clean -d -x -f"/>
290 </exec>
291 <mkdir dir="${distrib.dir}/dist/${build.version}"/>
292 <zip destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-src.zip" defaultexcludes="no">
293 <zipfileset dir="${build.dir}/snapshot-src" prefix="${snapshot.full.name}" defaultexcludes="no" excludes=".git/**"/>
294 </zip>
295 <tar destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-src.tar.gz"
296 compression="gzip" longfile="gnu" defaultexcludes="no">
297 <zipfileset dir="${build.dir}/snapshot-src" prefix="${snapshot.full.name}" defaultexcludes="no" excludes=".git/**"/>
298 </tar>
299 </target>
300
301 <target name="snapshot-bin-without-dependencies" depends="snapshot-metadata,jar,all-doc">
302 <mkdir dir="${distrib.dir}/dist/${build.version}"/>
303 <zip destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin.zip">
304 <zipfileset dir="${doc.build.dir}" prefix="${snapshot.full.name}/doc" excludes="**/reports/coverage/**,**/reports/test/**"/>
305 <zipfileset dir="${basedir}/src/example" prefix="${snapshot.full.name}/src/example"/>
306 <zipfileset dir="${basedir}" includes="NOTICE" fullpath="${snapshot.full.name}/NOTICE"/>
307 <zipfileset dir="${basedir}" includes="README" prefix="${snapshot.full.name}"/>
308 <zipfileset dir="${basedir}" includes="LICENSE*" prefix="${snapshot.full.name}"/>
309 <zipfileset dir="${basedir}" includes="CHANGES.txt" fullpath="${snapshot.full.name}/CHANGES.txt"/>
310 <zipfileset dir="${basedir}" includes="RELEASE_NOTES" fullpath="${snapshot.full.name}/RELEASE_NOTES"/>
311 <zipfileset dir="${src.dir}/org/apache/ivy/plugins/parser/xml" includes="ivy.xsd" fullpath="${snapshot.full.name}/ivy.xsd"/>
312 <zipfileset dir="${artifacts.build.dir}" includes="ivy.xml" fullpath="${snapshot.full.name}/ivy.xml"/>
313 <zipfileset dir="${basedir}" includes="build-for-bin-distrib.xml" fullpath="${snapshot.full.name}/build.xml"/>
314
315 <zipfileset dir="${artifacts.build.dir}/jars" includes="${final.name}" fullpath="${snapshot.full.name}/ivy-${build.version}.jar"/>
316 </zip>
317 <tar destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin.tar.gz"
318 compression="gzip" longfile="gnu">
319 <zipfileset src="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin.zip"/>
320 </tar>
321 </target>
322
323 <target name="snapshot-bin-with-dependencies" depends="snapshot-metadata,jar,all-doc">
324 <mkdir dir="${distrib.dir}/dist/${build.version}"/>
325 <delete dir="${build.dir}/lib"/>
326 <ivy:retrieve conf="default" pattern="${build.dir}/lib/[artifact]-[revision].[ext]"/>
327 <zip destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin-with-deps.zip">
328 <zipfileset dir="${doc.build.dir}" prefix="${snapshot.full.name}/doc" excludes="**/reports/coverage/**,**/reports/test/**"/>
329 <zipfileset dir="${basedir}/src/example" prefix="${snapshot.full.name}/src/example"/>
330 <zipfileset dir="${basedir}" includes="NOTICE" fullpath="${snapshot.full.name}/NOTICE"/>
331 <zipfileset dir="${basedir}" includes="README" prefix="${snapshot.full.name}"/>
332 <zipfileset dir="${basedir}" includes="LICENSE*" prefix="${snapshot.full.name}"/>
333 <zipfileset dir="${basedir}" includes="CHANGES.txt" fullpath="${snapshot.full.name}/CHANGES.txt"/>
334 <zipfileset dir="${basedir}" includes="RELEASE_NOTES" fullpath="${snapshot.full.name}/RELEASE_NOTES"/>
335 <zipfileset dir="${src.dir}/org/apache/ivy/plugins/parser/xml" includes="ivy.xsd" fullpath="${snapshot.full.name}/ivy.xsd"/>
336 <zipfileset dir="${artifacts.build.dir}" includes="ivy.xml" fullpath="${snapshot.full.name}/ivy.xml"/>
337
338 <zipfileset dir="${artifacts.build.dir}/jars" includes="${final.name}" fullpath="${snapshot.full.name}/ivy-${build.version}.jar"/>
339
340 <zipfileset dir="${build.dir}/lib" prefix="${snapshot.full.name}/lib" excludes="ant-*.jar,bcpg-*.jar,bcprov*.jar"/>
341 </zip>
342 <tar destfile="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin-with-deps.tar.gz"
343 compression="gzip" longfile="gnu">
344 <zipfileset src="${distrib.dir}/dist/${build.version}/${snapshot.full.name}-bin-with-deps.zip"/>
345 </tar>
346 </target>
347
348 <target name="snapshot-bin"
349 depends="snapshot-bin-with-dependencies,snapshot-bin-without-dependencies"/>
350
351 <target name="release-xsd" depends="init-snapshot">
352 <!-- copies current ivy xml schema to doc source, so that it will be available from web site -->
353 <copy file="${src.dir}/org/apache/ivy/plugins/parser/xml/ivy.xsd" todir="${doc.src.dir}"/>
354 </target>
355
356 <target name="snapshot-maven2" depends="init-snapshot,snapshot-metadata,jar,sources,javadoc">
357 <property name="m2.distrib.dir" value="${distrib.dir}/maven2/${build.version}"/>
358 <ivy:makepom ivyfile="${artifacts.build.dir}/ivy.xml"
359 pomfile="${m2.distrib.dir}/ivy-${build.version}.pom"
360 templatefile="${basedir}/src/etc/makepom/pom.template">
361 <mapping conf="core" scope="compile"/>
362 <mapping conf="test" scope="test"/>
363 </ivy:makepom>
364 <copy file="${artifacts.build.dir}/jars/${final.name}"
365 tofile="${m2.distrib.dir}/ivy-${build.version}.jar"/>
366 <!-- jar javadocs -->
367 <jar destfile="${m2.distrib.dir}/ivy-${build.version}-javadoc.jar">
368 <fileset dir="${javadoc.build.dir}"/>
369 </jar>
370 <!-- copy sources jar -->
371 <copy file="${artifacts.build.dir}/sources/${final.name}"
372 tofile="${m2.distrib.dir}/ivy-${build.version}-sources.jar"/>
373
374 <checksum algorithm="sha1">
375 <fileset dir="${m2.distrib.dir}">
376 <include name="*.pom"/>
377 <include name="*.jar"/>
378 </fileset>
379 </checksum>
380 <checksum algorithm="sha-512" fileext=".sha512">
381 <fileset dir="${m2.distrib.dir}">
382 <include name="*.pom"/>
383 <include name="*.jar"/>
384 </fileset>
385 </checksum>
386 </target>
387
388 <target name="snapshot-checksums">
389 <checksum algorithm="sha1">
390 <fileset dir="${distrib.dir}/dist/${build.version}">
391 <include name="*.pom"/>
392 <include name="*.jar"/>
393 <include name="*.zip"/>
394 <include name="*.gz"/>
395 </fileset>
396 </checksum>
397 <checksum algorithm="sha-512" fileext=".sha512">
398 <fileset dir="${distrib.dir}/dist/${build.version}">
399 <include name="*.pom"/>
400 <include name="*.jar"/>
401 <include name="*.zip"/>
402 <include name="*.gz"/>
403 </fileset>
404 </checksum>
405 </target>
406
407 <target name="snapshot-version">
408 <property name="version.prefix" value="${target.ivy.version}-dev-"/>
409 </target>
410
411 <target name="release-version">
412 <property name="build.version" value="${target.ivy.version}"/>
413 <echo>Setting version to ${build.version}</echo>
414 <condition property="status" value="release">
415 <matches pattern="^\d+\.\d+\.\d+$" string="${build.version}"/>
416 </condition>
417 <condition property="status" value="milestone">
418 <matches pattern="^\d+\.\d+\.\d+-(alpha|beta|rc)\d+$" string="${build.version}"/>
419 </condition>
420 <property name="status" value="integration"/>
421 <echo>Setting status to ${status}</echo>
422 </target>
423
424 <target name="sign" depends="init-ivy">
425 <property file="${user.home}/ivybuild.properties"/>
426 <input message="please enter your PGP password: " addproperty="pgp.password"/>
427 <input message="please enter your PGP keyId: " addproperty="pgp.keyId"/>
428
429 <ivy:retrieve conf="default" pattern="${build.dir}/lib/[artifact]-[revision].[ext]"/>
430
431 <taskdef resource="org/apache/ivy/ant/antlib.xml"
432 uri="antlib:org.apache.ivy.ant_2">
433 <classpath>
434 <fileset dir="${artifacts.build.dir}/jars" includes="${final.name}"/>
435 <fileset dir="${build.dir}/lib" excludes="ant-*.jar"/>
436 </classpath>
437 </taskdef>
438
439 <ivy2:settings id="sign.settingsId" file="ivysettings-release.xml"/>
440 <ivy2:cachepath organisation="org.apache.commons" settingsRef="sign.settingsId" transitive="false" log="download-only"
441 module="commons-openpgp" revision="1.0-SNAPSHOT" inline="true" pathid="openpgp.classpath"/>
442 <ivy2:cachepath organisation="org.bouncycastle" settingsRef="sign.settingsId" log="download-only"
443 module="bcprov-jdk16" revision="1.45" inline="true" pathid="bouncycastle.bcprov.classpath"/>
444 <ivy2:cachepath organisation="org.bouncycastle" settingsRef="sign.settingsId" transitive="false" log="download-only"
445 module="bcpg-jdk16" revision="1.45" inline="true" pathid="bouncycastle.bcpg.classpath"/>
446
447 <!--
448 For some reason, if we use the openpgp:signer task here directly, the bouncycastle security
449 provider cannot be loaded. If we launch it as a forked process everything works fine !?!
450 -->
451 <java classname="org.apache.tools.ant.launch.Launcher"
452 fork="true">
453 <classpath>
454 <fileset dir="${ant.home}" includes="**/*.jar"/>
455 <path refid="bouncycastle.bcprov.classpath"/>
456 <path refid="bouncycastle.bcpg.classpath"/>
457 <path refid="openpgp.classpath"/>
458 </classpath>
459 <arg line="-f build-release.xml"/>
460 <arg line="sign-internal"/>
461 <arg line="-Dpgp.password=${pgp.password}"/>
462 <arg line="-Dpgp.keyId=${pgp.keyId}"/>
463 </java>
464 </target>
465
466 <target name="sign-internal">
467 <property file="build.properties"/>
468 <taskdef resource="org/apache/commons/openpgp/ant/antlib.xml" uri="antlib:org.apache.commons.openpgp.ant"/>
469 <openpgp:signer secring="${user.home}/.gnupg/secring.gpg"
470 pubring="${user.home}/.gnupg/pubring.gpg"
471 password="${pgp.password}"
472 keyid="${pgp.keyId}"
473 asciiarmor="true">
474 <fileset dir="${distrib.dir}">
475 <include name="**/*.pom"/>
476 <include name="**/*.jar"/>
477 <include name="**/*.zip"/>
478 <include name="**/*.gz"/>
479 </fileset>
480 </openpgp:signer>
481 </target>
482
483 <target name="rat" depends="init-ivy">
484 <property name="rat.failOnError" value="true"/>
485 <ivy:cachepath organisation="org.apache.rat" module="apache-rat-tasks" revision="0.12"
486 inline="true" conf="default" pathid="rat.classpath"
487 log="download-only"/>
488
489 <typedef resource="org/apache/rat/anttasks/antlib.xml"
490 uri="antlib:org.apache.rat.anttasks"
491 classpathref="rat.classpath"/>
492
493 <delete dir="${rat.report.dir}"/>
494 <mkdir dir="${rat.report.dir}"/>
495 <rat:report xmlns:rat="antlib:org.apache.rat.anttasks" reportFile="${rat.report.dir}/rat-report.txt">
496 <fileset dir="${basedir}">
497 <exclude name=".classpath"/>
498 <exclude name="ReleaseInstructions"/>
499 <exclude name=".ivy2/**/*"/>
500 <exclude name="build/**/*"/>
501 <exclude name="bin/**/*"/>
502 <exclude name="**/*.md5"/>
503 <exclude name="**/*.sha1"/>
504 <exclude name="**/*.sha512"/>
505 <exclude name="**/*.txt"/>
506 <exclude name="**/MANIFEST*.MF"/>
507 <exclude name="**/*.json"/>
508 <exclude name="**/*.SHA-256"/>
509 <exclude name="**/*.SHA-512"/>
510 <exclude name="asciidoc/js/jquery.pack.js"/>
511 <exclude name="asciidoc/js/jquery.treeview.js"/>
512 </fileset>
513 </rat:report>
514
515 <fail message="Some files have missing or incorrect license information. Check RAT report for more details: ${rat.report.dir}/rat-report.txt">
516 <condition>
517 <and>
518 <not><resourcecontains resource="${rat.report.dir}/rat-report.txt" substring="0 Unknown Licenses" casesensitive="false"/></not>
519 <equals arg1="${rat.failOnError}" arg2="true"/>
520 </and>
521 </condition>
522 </fail>
523 </target>
524
525 <target name="upload-nexus" depends="release-version,init-ivy,jar">
526 <ivy:retrieve conf="default" pattern="${build.dir}/lib/[artifact]-[revision].[ext]"/>
527
528 <taskdef resource="org/apache/ivy/ant/antlib.xml"
529 uri="antlib:org.apache.ivy.ant_2">
530 <classpath>
531 <fileset dir="${artifacts.build.dir}/jars" includes="${final.name}"/>
532 <fileset dir="${build.dir}/lib" excludes="ant-*.jar"/>
533 </classpath>
534 </taskdef>
535
536 <property file="${user.home}/ivybuild.properties"/>
537 <input message="please enter your PGP password: " addproperty="pgp.password"/>
538 <input message="please enter your PGP keyId: " addproperty="pgp.keyId"/>
539
540 <input message="please enter your repository.apache.org username: " addproperty="upload.user"/>
541 <input message="please enter your repository.apache.org password: " addproperty="upload.password"/>
542
543 <ivy2:settings id="upload.settingsId" file="ivysettings-release.xml"/>
544 <ivy2:resolve file="${basedir}/build/artifact/ivy.xml" transitive="false"/>
545 <ivy2:publish organisation="org.apache.ivy"
546 module="ivy"
547 revision="${build.version}"
548 srcivypattern="${basedir}/build/artifact/ivy.xml"
549 artifactspattern="${basedir}/build/distrib/maven2/[revision]/[artifact]-[revision](-[classifier]).[ext]"
550 publishivy="false"
551 conf="core"
552 settingsRef="upload.settingsId"
553 resolver="nexus">
554 <!-- The standard maven2 artifacts -->
555 <artifact name="ivy" ext="pom" type="ivy"/>
556 <artifact name="ivy" ext="jar" type="sources" classifier="sources"/>
557 <artifact name="ivy" ext="jar" type="javadoc" classifier="javadoc"/>
558 </ivy2:publish>
559 </target>
560
561 <target name="prepare-snapshot"
562 depends="/localivy,clean-ivy-home,clean,clean-lib,snapshot-version,install,clean-examples,test-report"/>
563
564 <target name="snapshot"
565 depends="prepare-snapshot,snapshot-src,snapshot-bin,snapshot-maven2,snapshot-checksums"
566 description="used for nightly and integration builds"/>
567
568 <target name="release"
569 depends="release-version,/localivy,clean-ivy-home,clean,clean-lib,rat,snapshot"
570 description="make a new release of Ivy"/>
571
572 <target name="tagsdoc" depends="generate-doc"
573 description="generate tagsdoc.properties file which can be used in IvyDE for code completion documentation">
574 <scriptdef name="generate-tagsdoc" language="javascript">
575 <element name="fileset" type="fileset"/>
576 <attribute name="destFile"/>
577 <![CDATA[
578 fs = elements.get("fileset").get(0);
579 srcDir = fs.getDir(project);
580
581 // Get the files (array) of that fileset
582 srcFiles = fs.getDirectoryScanner(project).getIncludedFiles();
583
584 // iterate over that array
585 print('processing ' + srcFiles.length + ' source files...');
586
587 var xpath = javax.xml.xpath.XPathFactory.newInstance().newXPath();
588 out = new java.io.FileWriter(self.getProject().resolveFile(attributes.get("destfile")));
589 for (i = 0; i < srcFiles.length; i++) {
590 try {
591 // get the values via Java API
592 var file = new java.io.File(srcDir, srcFiles[i]);
593 print('processing ' + file + '...');
594
595 inputSource = new org.xml.sax.InputSource(new java.io.FileInputStream(file));
596
597 dbf = javax.xml.parsers.DocumentBuilderFactory.newInstance();
598 dbf.setValidating(false);
599 dbf.setIgnoringComments(false);
600 dbf.setIgnoringElementContentWhitespace(true);
601 dbf.setNamespaceAware(false);
602 dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
603 dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
604 builder = dbf.newDocumentBuilder();
605 document = builder.parse(inputSource);
606
607 var expression = "//span[contains(@class, 'ivysettings.')]";
608 var t = xpath.evaluate(expression, document, javax.xml.xpath.XPathConstants.NODE);
609 if (t == null) {
610 print('\tno tagdoc span found: ignored');
611 continue;
612 }
613 var id = t.getAttributes().getNamedItem("class").getTextContent();
614
615 out.write('##### ' + id + '\n');
616 out.write(id + ' = ' + t.getTextContent() + '\n');
617
618 text = (id === "ivysettings.resolvers") ? "Name" : "Attribute"
619 expression = "(//table/thead/tr/th[text()='" + text + "'])[1]/../../../tbody/tr/td[1]";
620 var atts = xpath.evaluate(expression, document, javax.xml.xpath.XPathConstants.NODESET);
621 for (j = 0; j < atts.getLength(); j++) {
622 name = atts.item(j).getTextContent().split(/[\s,]+/).pop()
623 out.write(id + '.@' + ((id === "ivysettings.resolvers") ? name.toLowerCase() : name) + ' = '
624 + xpath.evaluate("../td[2]", atts.item(j), javax.xml.xpath.XPathConstants.NODE)
625 .getTextContent().replace(/\n/g, " ").replace(/[\x00-\x1F\xA0-\xE1\xE3-\xFF]/g, "") + '\n');
626 }
627 } catch (e) {
628 print('\terror: ' + e);
629 }
630 }
631 out.close();
632 ]]>
633 </scriptdef>
634 <generate-tagsdoc destFile="tagsdoc.properties">
635 <fileset dir="${doc.build.dir}" includes="settings/**/*.html,resolver/**/*.html"/>
636 </generate-tagsdoc>
637 </target>
638
639 </project>
66 # * "License"); you may not use this file except in compliance
77 # * with the License. You may obtain a copy of the License at
88 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
9 # * https://www.apache.org/licenses/LICENSE-2.0
1010 # *
1111 # * Unless required by applicable law or agreed to in writing,
1212 # * software distributed under the License is distributed on an
2626 ant.classes.build.dir=${classes.build.dir}/ant
2727 optional.classes.build.dir=${classes.build.dir}/optional
2828 all.classes.build.dir=${classes.build.dir}/all
29 test.build.dir=${basedir}/build/test
30 artifacts.build.dir=${basedir}/build/artifact
31 distrib.dir=${basedir}/build/distrib
32 doc.build.dir=${basedir}/build/doc
33 reports.dir=${doc.build.dir}/reports
34 test.xml.dir=${build.dir}/test-report
35 test.report.dir=${reports.dir}/test
29 test.build.dir=${build.dir}/test
30 artifacts.build.dir=${build.dir}/artifact
31 distrib.dir=${build.dir}/distrib
32 doc.build.dir=${build.dir}/doc
33 reports.dir=${build.dir}/reports
34 test.xml.dir=${reports.dir}/test/xml
35 jacoco.log=${build.dir}/jacoco.data
36 test.report.dir=${reports.dir}/test/html
3637 coverage.report.dir=${reports.dir}/coverage
3738 javadoc.build.dir=${reports.dir}/api
39 test.javadoc.build.dir=${reports.dir}/test-api
3840 ivy.report.dir=${reports.dir}/ivy
39 doc.src.dir=${basedir}/doc
41 doc.src.dir=${basedir}/asciidoc
4042 checkstyle.report.dir=${reports.dir}/checkstyle
4143 checkstyle.src.dir=${basedir}/src/etc/checkstyle
4244 rat.report.dir=${reports.dir}/rat
4345
44 ivy.minimum.javaversion=1.5
46 ivy.minimum.javaversion=1.7
4547 debug.mode=on
4648 ivy.install.version=1.4.1
49 ivy.api.reference=2.4.0
4750
4851 #status=integration
52
53 # Comment out to fail builds if Checkstyle fails
54 #ignore.checkstyle=
4955
5056 test.class.pattern = *Test
5157
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
18 <project name="ivy" default="coverage-report" xmlns:ivy="antlib:org.apache.ivy.ant">
19
20 <property environment="env" />
21 <property file="version.properties" />
22 <property file="build.properties" />
23
24 <property name="final.name" value="ivy.jar" />
25
18 <project name="ivy" default="test-report" xmlns:ivy="antlib:org.apache.ivy.ant">
19
20 <property environment="env"/>
21 <property file="version.properties"/>
22 <property file="build.properties"/>
23
24 <property name="final.name" value="ivy.jar"/>
25 <!-- Java 7 runs into TLS protocol issues when dealing with repositories
26 that no longer support older protocols -->
27 <condition property="java.sysprop.https.protocols" value="" else="TLSv1.2">
28 <javaversion atleast="1.8"/>
29 </condition>
30
31
2632 <target name="init-ivy-user-home" unless="ivy.use.local.home">
2733 <condition property="ivy.home" value="${env.IVY_HOME}">
28 <isset property="env.IVY_HOME" />
34 <isset property="env.IVY_HOME"/>
2935 </condition>
30 <property name="ivy.home" value="${user.home}/.ivy2" />
31 </target>
32
36 <property name="ivy.home" value="${user.home}/.ivy2"/>
37 </target>
38
3339 <target name="init-ivy-local-home" if="ivy.use.local.home">
34 <property name="ivy.home" value="${basedir}/.ivy2" />
35 </target>
36
37 <target name="init-ivy-home" depends="init-ivy-user-home, init-ivy-local-home" />
38
39 <target name="init-ivy" depends="compile-bootstrap, init-ivy-home">
40 <property name="ivy.home" value="${basedir}/.ivy2"/>
41 </target>
42
43 <target name="init-ivy-home" depends="init-ivy-user-home,init-ivy-local-home"/>
44
45 <target name="init-ivy" depends="compile-bootstrap,init-ivy-home">
4046 <taskdef resource="org/apache/ivy/ant/antlib.xml"
41 uri="antlib:org.apache.ivy.ant">
47 uri="antlib:org.apache.ivy.ant">
4248 <classpath>
43 <pathelement location="${core.classes.build.dir}" />
44 <pathelement location="${bootstrap.classes.build.dir}" />
49 <pathelement location="${core.classes.build.dir}"/>
50 <pathelement location="${bootstrap.classes.build.dir}"/>
4551 </classpath>
4652 </taskdef>
47
48 <ivy:configure override="true" />
49 </target>
50
51 <target name="install" depends="init-ivy-home, jar"
52 description="build Ivy and install it in Ivy user home for builds using Ivy user home to load Ivy jar">
53 <property name="ivy.jar.file" value="${ivy.home}/jars/ivy.jar" />
54 <copy file="${artifacts.build.dir}/jars/${final.name}" tofile="${ivy.jar.file}" />
55 </target>
56
57 <target name="install-ant" depends="init-ivy-home, jar"
58 description="build Ivy and install it in Ant home lib">
53
54 <ivy:configure override="true"/>
55 </target>
56
57 <target name="install" depends="jar"
58 description="build Ivy and install it in Ivy user home for builds using Ivy user home to load Ivy jar">
59 <property name="ivy.jar.file" value="${ivy.home}/jars/ivy.jar"/>
60 <copy file="${artifacts.build.dir}/jars/${final.name}" tofile="${ivy.jar.file}"/>
61 </target>
62
63 <target name="install-ant" depends="jar"
64 description="build Ivy and install it in Ant home lib">
5965 <condition property="ant.home" value="${env.ANT_HOME}">
60 <isset property="env.ANT_HOME" />
66 <isset property="env.ANT_HOME"/>
6167 </condition>
62 <fail unless="ant.home" message="ANT_HOME environment variable or ant.home property required" />
63 <copy file="${artifacts.build.dir}/jars/${final.name}" tofile="${ant.home}/lib/ivy.jar" />
68 <fail unless="ant.home" message="ANT_HOME environment variable or ant.home property required"/>
69 <copy file="${artifacts.build.dir}/jars/${final.name}" tofile="${ant.home}/lib/ivy.jar"/>
6470 </target>
6571
6672 <!-- =================================================================
6975 <target name="init">
7076 <path id="lib.classpath">
7177 <fileset dir="${lib.dir}">
72 <include name="*.jar" />
78 <include name="*.jar"/>
7379 </fileset>
7480 </path>
7581 <path id="build.bootstrap.classpath">
76 <pathelement location="${core.classes.build.dir}" />
82 <pathelement location="${core.classes.build.dir}"/>
7783 </path>
7884 <path id="build.ant.classpath">
79 <pathelement location="${core.classes.build.dir}" />
80 <path refid="lib.classpath" />
85 <pathelement location="${core.classes.build.dir}"/>
86 <path refid="lib.classpath"/>
8187 </path>
8288 <path id="build.optional.classpath">
83 <path refid="build.ant.classpath" />
89 <path refid="build.ant.classpath"/>
8490 </path>
8591 <path id="run.classpath">
86 <pathelement location="${core.classes.build.dir}" />
87 <pathelement location="${ant.classes.build.dir}" />
88 <pathelement location="${optional.classes.build.dir}" />
89 <path refid="lib.classpath" />
92 <pathelement location="${core.classes.build.dir}"/>
93 <pathelement location="${ant.classes.build.dir}"/>
94 <pathelement location="${optional.classes.build.dir}"/>
95 <path refid="lib.classpath"/>
9096 </path>
9197 <path id="test.classpath">
92 <pathelement location="${coverage.classes.dir}" />
93 <fileset dir="${lib.dir}">
94 <include name="*.jar" />
95 <exclude name="ant.jar" />
96 <exclude name="ant-launcher.jar" />
97 <exclude name="ant-nodeps.jar"/>
98 <exclude name="ant-trax.jar"/>
99 </fileset>
100 <pathelement location="${core.classes.build.dir}" />
101 <pathelement location="${ant.classes.build.dir}" />
102 <pathelement location="${optional.classes.build.dir}" />
103 <pathelement path="${test.build.dir}" />
98 <fileset dir="${lib.dir}" />
99 <pathelement location="${core.classes.build.dir}"/>
100 <pathelement location="${ant.classes.build.dir}"/>
101 <pathelement location="${optional.classes.build.dir}"/>
102 <pathelement path="${test.build.dir}"/>
104103 </path>
105 </target>
106
104 <path id="javadoc.test.classpath">
105 <path refid="run.classpath"/>
106 <pathelement path="${test.build.dir}"/>
107 </path>
108 </target>
109
107110 <target name="prepare" depends="init">
108 <mkdir dir="${classes.build.dir}" />
109 <mkdir dir="${core.classes.build.dir}" />
110 <mkdir dir="${bootstrap.classes.build.dir}" />
111 <mkdir dir="${ant.classes.build.dir}" />
112 <mkdir dir="${optional.classes.build.dir}" />
113 <mkdir dir="${all.classes.build.dir}" />
114 <mkdir dir="${test.build.dir}" />
115 <mkdir dir="${artifacts.build.dir}" />
116 <mkdir dir="${test.report.dir}" />
117 <mkdir dir="${ivy.report.dir}" />
118 </target>
119
111 <mkdir dir="${classes.build.dir}"/>
112 <mkdir dir="${core.classes.build.dir}"/>
113 <mkdir dir="${bootstrap.classes.build.dir}"/>
114 <mkdir dir="${ant.classes.build.dir}"/>
115 <mkdir dir="${optional.classes.build.dir}"/>
116 <mkdir dir="${all.classes.build.dir}"/>
117 <mkdir dir="${test.build.dir}"/>
118 <mkdir dir="${artifacts.build.dir}"/>
119 <mkdir dir="${test.report.dir}"/>
120 </target>
121
120122 <target name="clean" description="delete all generated files keeping sources only">
121 <delete dir="${classes.build.dir}" />
122 <delete dir="${test.build.dir}" />
123 <delete dir="${artifacts.build.dir}" />
124 <delete dir="${test.report.dir}" />
125 <delete dir="${javadoc.build.dir}" />
126 <delete dir="${doc.build.dir}" />
127 <delete dir="${build.dir}" />
128 </target>
129
123 <delete dir="${classes.build.dir}"/>
124 <delete dir="${test.build.dir}"/>
125 <delete dir="${artifacts.build.dir}"/>
126 <delete dir="${ivy.report.dir}"/>
127 <delete dir="${test.report.dir}"/>
128 <delete dir="${javadoc.build.dir}"/>
129 <delete dir="${doc.build.dir}"/>
130 <delete dir="${build.dir}"/>
131 </target>
132
130133 <target name="clean-lib">
131 <delete dir="${lib.dir}" />
132 </target>
133
134 <delete dir="${lib.dir}"/>
135 </target>
136
134137 <target name="clean-ivy-cache" depends="init-ivy-home">
135 <delete dir="${ivy.home}/cache" />
136 </target>
137
138 <delete dir="${ivy.home}/cache"/>
139 </target>
140
138141 <target name="clean-ivy-home" depends="init-ivy-home">
139 <delete dir="${ivy.home}" />
140 </target>
141
142 <delete dir="${ivy.home}"/>
143 </target>
144
142145 <target name="clean-examples" description="clean all examples">
143146 <subant target="clean" failonerror="false">
144 <fileset dir="${example.dir}" includes="**/build.xml" />
145 </subant>
146 </target>
147
148 <target name="clean-all" depends="clean, clean-lib, clean-examples" />
149
147 <fileset dir="${example.dir}" includes="**/build.xml"/>
148 </subant>
149 </target>
150
151 <target name="clean-all" depends="clean-examples,clean,clean-lib"/>
152
150153 <target name="/noresolve" description="use to skip dependency resolution">
151 <property name="no.resolve" value="true" />
152 </target>
153
154 <property name="no.resolve" value="true"/>
155 </target>
156
154157 <target name="/notest" description="use to skip tests">
155 <property name="skip.test" value="true" />
156 </target>
157
158 <property name="skip.test" value="true"/>
159 </target>
160
158161 <target name="/nojavadoc" description="use to skip javadoc">
159 <property name="skip.javadoc" value="true" />
160 </target>
161
162 <property name="skip.javadoc" value="true"/>
163 </target>
164
162165 <target name="/localivy" description="use a local ivy home">
163 <property name="ivy.use.local.home" value="true" />
164 </target>
165
166 <property name="ivy.use.local.home" value="true"/>
167 </target>
168
166169 <target name="/offline" depends="/noresolve" description="use to indicate no internet connection is available">
167 <property name="offline" value="true" />
168 </target>
169
170 <property name="offline" value="true"/>
171 </target>
172
170173 <target name="default-version">
171 <tstamp>
172 <format property="pubdate" pattern="yyyyMMddHHmmss" />
174 <tstamp>
175 <format property="pubdate" pattern="yyyyMMddHHmmss"/>
173176 </tstamp>
174 <property name="version.prefix" value="${target.ivy.version}-local-" />
175 <property name="build.version" value="${version.prefix}${pubdate}" />
176 <property name="bundle.version" value="${target.ivy.bundle.version}.${target.ivy.bundle.version.qualifier}${pubdate}" />
177 <property name="version.prefix" value="${target.ivy.version}-local-"/>
178 <property name="build.version" value="${version.prefix}${pubdate}"/>
179 <property name="bundle.version" value="${target.ivy.bundle.version}.${target.ivy.bundle.version.qualifier}${pubdate}"/>
177180 </target>
178181
179182 <!-- =================================================================
184187 </target>
185188
186189 <target name="compile-core" depends="prepare">
187 <javac srcdir="${src.dir}"
188 destdir="${core.classes.build.dir}"
189 sourcepath=""
190 source="${ivy.minimum.javaversion}"
191 target="${ivy.minimum.javaversion}"
192 debug="${debug.mode}"
193 includeantruntime="no">
194 <excludesfile name="ant.patterns" />
195 <excludesfile name="optional.patterns" />
190 <javac srcdir="${src.dir}"
191 destdir="${core.classes.build.dir}"
192 sourcepath=""
193 source="${ivy.minimum.javaversion}"
194 target="${ivy.minimum.javaversion}"
195 debug="${debug.mode}"
196 includeantruntime="no">
197 <excludesfile name="ant.patterns"/>
198 <excludesfile name="optional.patterns"/>
196199 </javac>
197200 <copy todir="${core.classes.build.dir}" includeEmptyDirs="false">
198201 <fileset dir="${src.dir}">
199 <exclude name="**/*.java" />
200 <excludesfile name="ant.patterns" />
201 <excludesfile name="optional.patterns" />
202 <exclude name="**/*.java"/>
203 <excludesfile name="ant.patterns"/>
204 <excludesfile name="optional.patterns"/>
202205 </fileset>
203206 </copy>
204
207
205208 <!-- copy settings files for backward compatibility with ivyconf naming -->
206209 <copy file="${core.classes.build.dir}/org/apache/ivy/core/settings/ivysettings-local.xml"
207 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-local.xml" />
210 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-local.xml"/>
208211 <copy file="${core.classes.build.dir}/org/apache/ivy/core/settings/ivysettings-default-chain.xml"
209 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-default-chain.xml" />
212 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-default-chain.xml"/>
210213 <copy file="${core.classes.build.dir}/org/apache/ivy/core/settings/ivysettings-main-chain.xml"
211 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-main-chain.xml" />
214 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-main-chain.xml"/>
212215 <copy file="${core.classes.build.dir}/org/apache/ivy/core/settings/ivysettings-public.xml"
213 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-public.xml" />
216 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-public.xml"/>
214217 <copy file="${core.classes.build.dir}/org/apache/ivy/core/settings/ivysettings-shared.xml"
215 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-shared.xml" />
218 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf-shared.xml"/>
216219 <copy file="${core.classes.build.dir}/org/apache/ivy/core/settings/ivysettings.xml"
217 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf.xml" />
218 </target>
219
220 <!-- Build the Ant tasks with the current Ant runtime -->
220 tofile="${core.classes.build.dir}/org/apache/ivy/core/settings/ivyconf.xml"/>
221 </target>
222
223 <!-- Build the Ant tasks with the current Ant runtime -->
221224 <target name="compile-bootstrap" depends="compile-core">
222 <javac srcdir="${src.dir}"
223 destdir="${bootstrap.classes.build.dir}"
224 sourcepath=""
225 classpathref="build.bootstrap.classpath"
226 source="${ivy.minimum.javaversion}"
227 target="${ivy.minimum.javaversion}"
228 debug="${debug.mode}"
229 includeantruntime="yes">
230 <includesfile name="ant.patterns" />
225 <javac srcdir="${src.dir}"
226 destdir="${bootstrap.classes.build.dir}"
227 sourcepath=""
228 classpathref="build.bootstrap.classpath"
229 source="${ivy.minimum.javaversion}"
230 target="${ivy.minimum.javaversion}"
231 debug="${debug.mode}"
232 includeantruntime="yes">
233 <includesfile name="ant.patterns"/>
231234 </javac>
232235 <copy todir="${bootstrap.classes.build.dir}" includeEmptyDirs="false">
233236 <fileset dir="${src.dir}">
234 <includesfile name="ant.patterns" />
235 <exclude name="**/*.java" />
237 <includesfile name="ant.patterns"/>
238 <exclude name="**/*.java"/>
236239 </fileset>
237240 </copy>
238241 </target>
239
240 <!-- Build the Ant tasks with the minimal Ant runtime -->
241 <target name="compile-ant" depends="compile-core, resolve">
242 <javac srcdir="${src.dir}"
243 destdir="${ant.classes.build.dir}"
244 sourcepath=""
245 classpathref="build.ant.classpath"
246 source="${ivy.minimum.javaversion}"
247 target="${ivy.minimum.javaversion}"
248 debug="${debug.mode}"
249 includeantruntime="no">
250 <includesfile name="ant.patterns" />
242
243 <!-- Build the Ant tasks with the minimal Ant runtime -->
244 <target name="compile-ant" depends="compile-core,resolve">
245 <javac srcdir="${src.dir}"
246 destdir="${ant.classes.build.dir}"
247 sourcepath=""
248 classpathref="build.ant.classpath"
249 source="${ivy.minimum.javaversion}"
250 target="${ivy.minimum.javaversion}"
251 debug="${debug.mode}"
252 includeantruntime="no">
253 <includesfile name="ant.patterns"/>
251254 </javac>
252255 <copy todir="${ant.classes.build.dir}" includeEmptyDirs="false">
253256 <fileset dir="${src.dir}">
254 <includesfile name="ant.patterns" />
255 <exclude name="**/*.java" />
257 <includesfile name="ant.patterns"/>
258 <exclude name="**/*.java"/>
256259 </fileset>
257260 </copy>
258
261
259262 <!-- copy antlib for backward compatibility with fr.jayasoft.ivy package -->
260 <copy file="${ant.classes.build.dir}/org/apache/ivy/ant/antlib.xml"
261 todir="${ant.classes.build.dir}/fr/jayasoft/ivy/ant" />
262 </target>
263
264 <target name="compile-optional" depends="compile-ant, resolve">
265 <javac srcdir="${src.dir}"
266 destdir="${optional.classes.build.dir}"
267 sourcepath=""
268 classpathref="build.optional.classpath"
269 source="${ivy.minimum.javaversion}"
270 target="${ivy.minimum.javaversion}"
271 debug="${debug.mode}"
272 includeantruntime="no">
273 <includesfile name="optional.patterns" />
274 <includesfile name="ant.patterns" />
263 <copy file="${ant.classes.build.dir}/org/apache/ivy/ant/antlib.xml"
264 todir="${ant.classes.build.dir}/fr/jayasoft/ivy/ant"/>
265 </target>
266
267 <target name="compile-optional" depends="compile-ant">
268 <javac srcdir="${src.dir}"
269 destdir="${optional.classes.build.dir}"
270 sourcepath=""
271 classpathref="build.optional.classpath"
272 source="${ivy.minimum.javaversion}"
273 target="${ivy.minimum.javaversion}"
274 debug="${debug.mode}"
275 includeantruntime="no">
276 <includesfile name="optional.patterns"/>
277 <includesfile name="ant.patterns"/>
275278 </javac>
276279 <copy todir="${core.classes.build.dir}" includeEmptyDirs="false">
277280 <fileset dir="${src.dir}">
278 <includesfile name="optional.patterns" />
279 <exclude name="**/*.java" />
281 <includesfile name="optional.patterns"/>
282 <exclude name="**/*.java"/>
280283 </fileset>
281284 </copy>
282285 </target>
284287 <!-- =================================================================
285288 Create the two jar files (Ivy core and Ivy core + Ant tasks)
286289 ================================================================= -->
287 <target name="jar" depends="compile-optional, default-version" description="Create Jar files">
290 <target name="jar" depends="compile-optional,default-version" description="Create Jar files">
288291 <!-- identify compiled ivy version -->
289 <echo message="version=${build.version}${line.separator}" file="${core.classes.build.dir}/module.properties" append="true" />
290 <echo message="date=${pubdate}${line.separator}" file="${core.classes.build.dir}/module.properties" append="true" />
291
292 <mkdir dir="${artifacts.build.dir}/jars/"/>
293
294 <!--
295 there is a default Bundle-Version attribute in the source MANIFEST, used to ease
296 development in eclipse.
297 We remove this line to make sure we get the Bundle-Version as set in the jar task
298 -->
299 <copy file="${basedir}/META-INF/MANIFEST.MF" tofile="${artifacts.build.dir}/MANIFEST.MF">
300 <filterchain>
301 <replaceregex pattern="Bundle-Version:.*" replace="Bundle-Version: ${bundle.version}" byline="true" />
302 </filterchain>
303 </copy>
292 <echo message="version=${build.version}${line.separator}" file="${core.classes.build.dir}/module.properties" append="true"/>
293 <echo message="date=${pubdate}${line.separator}" file="${core.classes.build.dir}/module.properties" append="true"/>
294
295 <mkdir dir="${artifacts.build.dir}/jars/"/>
296
297 <!--
298 there is a default Bundle-Version attribute in the source MANIFEST, used to ease
299 development in eclipse.
300 We remove this line to make sure we get the Bundle-Version as set in the jar task
301 -->
302 <copy file="${basedir}/META-INF/MANIFEST.MF" tofile="${artifacts.build.dir}/MANIFEST.MF">
303 <filterchain>
304 <replaceregex pattern="Bundle-Version:.*" replace="Bundle-Version: ${bundle.version}" byline="true"/>
305 </filterchain>
306 </copy>
304307
305308 <copy todir="${all.classes.build.dir}">
306 <fileset dir="${core.classes.build.dir}" />
307 <fileset dir="${ant.classes.build.dir}" />
308 <fileset dir="${optional.classes.build.dir}" />
309 <fileset dir="${core.classes.build.dir}"/>
310 <fileset dir="${ant.classes.build.dir}"/>
311 <fileset dir="${optional.classes.build.dir}"/>
309312 </copy>
310313
311314 <jar destfile="${artifacts.build.dir}/jars/${final.name}"
312 manifest="${artifacts.build.dir}/MANIFEST.MF">
313 <metainf dir="${basedir}" includes="LICENSE,NOTICE" />
315 manifest="${artifacts.build.dir}/MANIFEST.MF">
316 <metainf dir="${basedir}" includes="LICENSE,NOTICE"/>
314317 <manifest>
315 <attribute name="Specification-Title" value="Apache Ivy with Ant tasks" />
316 <attribute name="Specification-Version" value="${build.version}" />
317 <attribute name="Specification-Vendor" value="Apache Software Foundation" />
318 <attribute name="Implementation-Title" value="org.apache.ivy" />
319 <attribute name="Implementation-Version" value="${build.version}" />
320 <attribute name="Implementation-Vendor" value="Apache Software Foundation" />
321 <attribute name="Implementation-Vendor-Id" value="org.apache" />
322 <attribute name="Extension-name" value="org.apache.ivy" />
323 <attribute name="Build-Version" value="${build.version}" />
318 <attribute name="Specification-Title" value="Apache Ivy with Ant tasks"/>
319 <attribute name="Specification-Version" value="${build.version}"/>
320 <attribute name="Specification-Vendor" value="Apache Software Foundation"/>
321 <attribute name="Implementation-Title" value="org.apache.ivy"/>
322 <attribute name="Implementation-Version" value="${build.version}"/>
323 <attribute name="Implementation-Vendor" value="Apache Software Foundation"/>
324 <attribute name="Implementation-Vendor-Id" value="org.apache"/>
325 <attribute name="Extension-name" value="org.apache.ivy"/>
326 <attribute name="Build-Version" value="${build.version}"/>
324327 </manifest>
325 <fileset dir="${all.classes.build.dir}" />
328 <fileset dir="${all.classes.build.dir}"/>
326329 </jar>
327 <!-- copy main jar to ease its use as an OSGi bundle -->
328 <copy file="${artifacts.build.dir}/jars/${final.name}"
329 tofile="${artifacts.build.dir}/org.apache.ivy_${bundle.version}.jar" />
330 <!-- copy main jar to ease its use as an OSGi bundle -->
331 <copy file="${artifacts.build.dir}/jars/${final.name}"
332 tofile="${artifacts.build.dir}/org.apache.ivy_${bundle.version}.jar"/>
330333
331334 <!-- clean generated module properties file -->
332 <delete file="${core.classes.build.dir}/module.properties" />
333 </target>
334
335 <!-- =================================================================
335 <delete file="${core.classes.build.dir}/module.properties"/>
336 </target>
337
338 <!-- =================================================================
336339 PUBLISH LOCAL
337340 ================================================================= -->
341 <target name="fixcrlf">
342 <property name="eol.native.includes"
343 value="**/*.html,**/*.json,**/*.java,**/*.xml,**/*.txt,**/*.MF,**/*.properties,**/*.patterns,**/*.pom,**/*.xsl,**/*.css"/>
344 <property name="eol.native.excludes"
345 value="build/**,bin/**,lib/**"/>
346
347 <fileset id="eol.native.fileset"
348 dir="${basedir}"
349 includes="${eol.native.includes}"
350 excludes="${eol.native.excludes}"/>
351
352 <fixcrlf srcdir="${basedir}"
353 includes="${eol.native.includes}"
354 excludes="${eol.native.excludes}"/>
355 </target>
356
357 <target name="sources" depends="default-version" description="Create source archive files">
358 <mkdir dir="${artifacts.build.dir}/sources/"/>
359 <jar destfile="${artifacts.build.dir}/sources/${final.name}">
360 <metainf dir="${basedir}" includes="LICENSE,NOTICE"/>
361 <manifest>
362 <attribute name="Specification-Title" value="Apache Ivy Sources"/>
363 <attribute name="Specification-Version" value="${build.version}"/>
364 <attribute name="Specification-Vendor" value="Apache Software Foundation"/>
365 </manifest>
366 <fileset dir="${src.dir}"/>
367 </jar>
368 </target>
369
338370 <target name="publish-local" depends="jar,sources" description="publishes Ivy to Ivy local repository">
339371 <ivy:publish resolver="local" pubrevision="${build.version}"
340 artifactsPattern="${artifacts.build.dir}/[type]s/[artifact].[ext]"
341 forcedeliver="true" />
342 </target>
343
344 <!-- =================================================================
372 artifactsPattern="${artifacts.build.dir}/[type]s/[artifact].[ext]"
373 forcedeliver="true"/>
374 </target>
375
376 <!-- =================================================================
345377 TESTS
346378 ================================================================= -->
379 <target name="build-test" depends="jar">
380 <javac srcdir="${test.dir}"
381 destdir="${test.build.dir}"
382 classpathref="run.classpath"
383 source="${ivy.minimum.javaversion}"
384 target="${ivy.minimum.javaversion}"
385 debug="${debug.mode}"
386 encoding="UTF-8"
387 includeantruntime="no"/>
388 <copy todir="${test.build.dir}">
389 <fileset dir="${test.dir}">
390 <exclude name="**/*.java"/>
391 </fileset>
392 </copy>
393 </target>
394
347395 <target name="build-custom-resolver-jar" depends="jar">
348 <mkdir dir="${build.dir}/custom-classpath" />
349 <javac srcdir="${basedir}/test/custom-classpath"
350 destdir="${build.dir}/custom-classpath"
351 classpathref="run.classpath"
352 source="${ivy.minimum.javaversion}"
353 target="${ivy.minimum.javaversion}"
354 debug="${debug.mode}"
355 includeantruntime="no" />
356 <jar destfile="${test.dir}/org/apache/ivy/core/settings/custom-resolver.jar"
357 basedir="${build.dir}/custom-classpath" />
396 <mkdir dir="${build.dir}/custom-classpath"/>
397 <javac srcdir="${basedir}/test/custom-classpath"
398 destdir="${build.dir}/custom-classpath"
399 classpathref="run.classpath"
400 source="${ivy.minimum.javaversion}"
401 target="${ivy.minimum.javaversion}"
402 debug="${debug.mode}"
403 includeantruntime="no"/>
404 <jar destfile="${test.dir}/org/apache/ivy/core/settings/custom-resolver.jar"
405 basedir="${build.dir}/custom-classpath"/>
358406 </target>
359407
360408 <target name="init-tests-offline" if="offline">
361409 <fileset id="test.fileset" dir="${test.dir}">
362 <include name="**/${test.class.pattern}.java" />
363 <exclude name="**/Abstract*Test.java" />
364 <not><contains text="remote.test" /></not>
365 </fileset>
366 </target>
367
410 <include name="**/${test.class.pattern}.java"/>
411 <exclude name="**/Abstract*Test.java"/>
412 <not><contains text="remote.test"/></not>
413 </fileset>
414 </target>
415
368416 <target name="init-tests-online" unless="offline">
369417 <fileset id="test.fileset" dir="${test.dir}">
370 <include name="**/${test.class.pattern}.java" />
371 <exclude name="**/Abstract*Test.java" />
372 </fileset>
373 </target>
374
375 <target name="init-tests" depends="init-tests-offline, init-tests-online" />
376
377 <target name="emma" depends="jar" unless="skip.test">
378 <ivy:cachepath organisation="emma" module="emma" revision="2.0.5312"
379 inline="true" conf="default" pathid="emma.classpath"
380 log="download-only" />
381 <ivy:cachepath organisation="emma" module="emma_ant" revision="2.0.5312"
382 inline="true" conf="default" pathid="emma.ant.classpath" transitive="false"
383 log="download-only" />
384 <taskdef resource="emma_ant.properties">
385 <classpath refid="emma.classpath" />
386 <classpath refid="emma.ant.classpath" />
387 </taskdef>
388 <property name="emma.enabled" value="true" />
389 <property name="coverage.dir" value="${build.dir}/coverage" />
390 <property name="coverage.classes.dir" value="${coverage.dir}/classes" />
391 <mkdir dir="${coverage.dir}" />
392 <mkdir dir="${coverage.classes.dir}" />
393 <emma enabled="${emma.enabled}">
394 <instr mode="copy"
395 destdir="${coverage.dir}/classes"
396 metadatafile="${coverage.dir}/metadata.emma">
397 <instrpath>
398 <pathelement location="${core.classes.build.dir}" />
399 <pathelement location="${ant.classes.build.dir}" />
400 <pathelement location="${optional.classes.build.dir}" />
401 </instrpath>
402 </instr>
403 </emma>
404 <delete file="${coverage.dir}/coverage.emma" />
405 <!-- add emma path to test path, because emma jars need to be available when running
406 instrumented classes -->
407 <ivy:addpath topath="test.classpath" first="true">
408 <pathelement location="${coverage.dir}/classes" />
409 <path refid="emma.classpath" />
410 </ivy:addpath>
411 </target>
412
413 <target name="build-test" depends="jar">
414 <javac srcdir="${test.dir}"
415 destdir="${test.build.dir}"
416 classpathref="run.classpath"
417 source="${ivy.minimum.javaversion}"
418 target="${ivy.minimum.javaversion}"
419 debug="${debug.mode}"
420 encoding="ISO-8859-1"
421 includeantruntime="no" />
422 <copy todir="${test.build.dir}">
423 <fileset dir="${test.dir}">
424 <exclude name="**/*.java" />
425 </fileset>
426 </copy>
427 </target>
428
429 <target name="prepare-osgi-tests" depends="resolve" unless="skip.test">
430 <ant dir="${basedir}/test/test-repo" target="generate-bundles" />
431 </target>
418 <include name="**/${test.class.pattern}.java"/>
419 <exclude name="**/Abstract*Test.java"/>
420 </fileset>
421 </target>
422
423 <target name="init-tests" depends="init-tests-offline,init-tests-online"/>
424
425 <target name="prepare-osgi-tests" depends="resolve" unless="skip.test">
426 <ant dir="${basedir}/test/test-repo" target="generate-bundles"/>
427 </target>
432428
433429 <target name="prepare-test-jar-repositories" unless="skip.test">
434 <mkdir dir="${basedir}/test/jar-repos" />
430 <mkdir dir="${basedir}/test/jar-repos"/>
435431 <jar destfile="${basedir}/test/jar-repos/jarrepo1.jar" >
436 <fileset dir="${basedir}/test/repositories/1" />
432 <fileset dir="${basedir}/test/repositories/1"/>
437433 </jar>
438434 <jar destfile="${basedir}/test/jar-repos/jarrepo1_subdir.jar">
439 <fileset dir="${basedir}/test/repositories" includes="1/**/*" />
435 <fileset dir="${basedir}/test/repositories" includes="1/**/*"/>
440436 </jar>
441437 </target>
442438
443 <target name="test-internal" depends="build-test, init-tests, prepare-osgi-tests, prepare-test-jar-repositories" unless="skip.test">
444 <mkdir dir="${test.xml.dir}" />
445
446 <junit
447 haltonfailure="off"
448 haltonerror="off"
449 errorproperty="test.failed"
450 failureproperty="test.failed"
451 showoutput="no"
452 printsummary="yes"
453 includeantruntime="yes"
454 dir="${basedir}"
455 fork="true">
456 <classpath>
457 <path refid="test.classpath" />
458 <pathelement path="${ant.home}/lib/ant-nodeps.jar"/>
459 <pathelement path="${ant.home}/lib/ant-trax.jar"/>
460 </classpath>
461
462 <!-- pass the proxy properties to the forked junit process to use correct proxy -->
463 <syspropertyset>
464 <propertyref prefix="http" />
465 </syspropertyset>
466 <jvmarg value="-Demma.coverage.out.file=${coverage.dir}/coverage.emma" />
467 <jvmarg value="-Demma.coverage.out.merge=true" />
468
469 <!-- Added this to test IVY-65 -->
470 <jvmarg value="-Duser.region=TR" />
471 <jvmarg value="-Duser.language=tr" />
472
473 <formatter type="xml"/>
474 <batchtest todir="${test.xml.dir}">
475 <fileset refid="test.fileset" />
476 </batchtest>
477 </junit>
439 <target name="init-jacoco" depends="jar" unless="skip.test">
440 <ivy:cachepath organisation="org.jacoco" module="org.jacoco.ant" revision="0.8.3"
441 inline="true" conf="default" pathid="jacoco.classpath" log="download-only"/>
442 <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml"
443 classpathref="jacoco.classpath"/>
444 </target>
445
446 <target name="test-internal" depends="build-test,init-tests,prepare-osgi-tests,prepare-test-jar-repositories,init-jacoco" unless="skip.test">
447 <mkdir dir="${test.xml.dir}"/>
448
449 <!-- multiple runs into the same logfile let the later report generation fail -->
450 <delete file="${jacoco.log}"/>
451 <jacoco:coverage xmlns:jacoco="antlib:org.jacoco.ant" destfile="${jacoco.log}"
452 exclclassloader="sun.reflect.DelegatingClassLoader:javassist.Loader">
453 <junit
454 haltonfailure="off"
455 haltonerror="off"
456 errorproperty="test.failed"
457 failureproperty="test.failed"
458 showoutput="no"
459 printsummary="yes"
460 includeantruntime="no"
461 dir="${basedir}"
462 tempdir="${build.dir}"
463 fork="true">
464 <classpath>
465 <path refid="test.classpath"/>
466 </classpath>
467
468 <!-- pass the proxy properties to the forked junit process to use correct proxy -->
469 <syspropertyset>
470 <propertyref prefix="http"/>
471 </syspropertyset>
472 <!-- We select specific HTTPS protocols, based on the Java version we are running
473 on -->
474 <sysproperty key="https.protocols" value="${java.sysprop.https.protocols}"/>
475
476 <!-- Added this to test IVY-65 -->
477 <jvmarg value="-Duser.region=TR"/>
478 <jvmarg value="-Duser.language=tr"/>
479
480 <formatter type="xml"/>
481 <batchtest todir="${test.xml.dir}">
482 <fileset refid="test.fileset"/>
483 </batchtest>
484 </junit>
485 </jacoco:coverage>
478486 </target>
479487
480488 <target name="test" depends="test-internal" description="Run the test">
481489 <fail if="test.failed"
482 message="At least one test has failed. See logs (in ${test.xml.dir}) for details (use the target test-report to run the test with a report)" />
483 </target>
484
490 message="At least one test has failed. See logs (in ${test.xml.dir}) for details (use the target test-report to run the test with a report)"/>
491 </target>
492
485493 <!-- =================================================================
486494 REPORTS AND DOCUMENTATION
487495 ================================================================= -->
488 <target name="test-report" depends="test-internal" unless="skip.test">
496 <target name="test-report" depends="test-internal" unless="skip.test"
497 description="run tests with instrumentation and generate coverage report">
489498 <junitreport todir="${test.xml.dir}">
490499 <fileset dir="${test.xml.dir}">
491 <include name="TEST-*.xml" />
492 </fileset>
493 <report format="frames" todir="${test.report.dir}" />
500 <include name="TEST-*.xml"/>
501 </fileset>
502 <report format="frames" todir="${test.report.dir}"/>
494503 </junitreport>
504
505 <mkdir dir="${coverage.report.dir}"/>
506 <jacoco:report xmlns:jacoco="antlib:org.jacoco.ant">
507 <executiondata>
508 <file file="${jacoco.log}"/>
509 </executiondata>
510
511 <structure name="Ivy">
512 <classfiles>
513 <fileset dir="${classes.build.dir}"/>
514 </classfiles>
515 <sourcefiles encoding="UTF-8">
516 <fileset dir="${src.dir}"/>
517 </sourcefiles>
518 </structure>
519
520 <html destdir="${coverage.report.dir}"/>
521 </jacoco:report>
522
495523 <fail if="test.failed"
496 message="At least one test has failed. See logs (in ${test.xml.dir}) or report (in ${test.report.dir})" />
497 </target>
498
499 <target name="coverage-report" depends="emma, test-report" unless="skip.test"
500 description="run tests with instrumentation and generate coverage report">
501 <mkdir dir="${coverage.report.dir}" />
502 <emma>
503 <report sourcepath="${src.dir}">
504 <fileset dir="${coverage.dir}">
505 <include name="*.emma" />
506 </fileset>
507
508 <txt outfile="${coverage.report.dir}/coverage.txt" />
509 <html outfile="${coverage.report.dir}/coverage.html" />
510 </report>
511 </emma>
512 </target>
513
514 <target name="ivy-report" depends="resolve">
515 <ivy:report todir="${ivy.report.dir}"/>
516 </target>
517
518 <target name="javadoc" unless="skip.javadoc">
519 <javadoc destdir="${javadoc.build.dir}" useexternalfile="true">
520 <fileset dir="${src.dir}" includes="**/*.java" />
524 message="At least one test has failed. See logs (in ${test.xml.dir}) or report (in ${test.report.dir})"/>
525 </target>
526
527 <target name="coverage-report" depends="test-report"/>
528
529 <target name="ivy-report" depends="resolve">
530 <mkdir dir="${ivy.report.dir}"/>
531 <ivy:report todir="${ivy.report.dir}"/>
532 </target>
533
534 <target name="init-japicmp" depends="jar" unless="skip.test">
535 <ivy:cachepath organisation="com.github.siom79.japicmp" module="japicmp-ant-task" revision="0.13.0"
536 inline="true" conf="default" pathid="japicmp.classpath" log="download-only"/>
537 <taskdef uri="antlib:japicmp.ant" resource="japicmp/ant/antlib.xml"
538 classpathref="japicmp.classpath"/>
539 <ivy:cachepath organisation="org.apache.ivy" module="ivy" revision="${ivy.api.reference}"
540 inline="true" conf="optional" pathid="ivyrefdeps.classpath" log="download-only"/>
541 <ivy:cachefileset organisation="org.apache.ivy" module="ivy" revision="${ivy.api.reference}"
542 inline="true" conf="master" setid="ivyref.fileset" log="download-only"/>
543 <pathconvert property="ivyref.name" refid="ivyref.fileset"/>
544 </target>
545
546 <target name="/japicmp-all" description="report status of all public APIs">
547 <property name="japicmp.all" value="true"/>
548 </target>
549
550 <target name="/japicmp-changed" description="report all changed public APIs">
551 <property name="japicmp.changed" value="true"/>
552 </target>
553
554 <target name="japicmp" depends="init-japicmp" unless="skip.test">
555 <property name="japicmp.all" value="false"/>
556 <property name="japicmp.changed" value="false"/>
557 <condition property="japicmp.binary" value="true" else="false">
558 <not>
559 <or>
560 <istrue value="${japicmp.all}"/>
561 <istrue value="${japicmp.changed}"/>
562 </or>
563 </not>
564 </condition>
565 <japicmp:japicmp xmlns:japicmp="antlib:japicmp.ant"
566 oldjar="${ivyref.name}"
567 newjar="${artifacts.build.dir}/jars/${final.name}"
568 oldclasspathref="ivyrefdeps.classpath"
569 newclasspathref="lib.classpath"
570 onlybinaryincompatible="${japicmp.binary}"
571 onlymodified="${japicmp.changed}"
572 htmloutputfile="${reports.dir}/japicmp.html"/>
573 </target>
574
575 <target name="javadoc" depends="init" unless="skip.javadoc">
576 <tstamp>
577 <format pattern="2007-yyyy" property="years"/>
578 </tstamp>
579 <property name="copyright" value="Copyright &amp;copy;${years} The Apache Software Foundation, Licensed under &lt;a href=&quot;https://www.apache.org/licenses/LICENSE-2.0.txt&quot;&gt;Apache License, Version 2.0&lt;/a&gt;."/>
580 <property name="title" value="Apache Ivy&amp;trade; dependency manager ${target.ivy.version} API"/>
581 <javadoc destdir="${javadoc.build.dir}"
582 useexternalfile="true"
583 windowtitle="Apache Ivy&amp;trade;"
584 doctitle="${title}"
585 bottom="${copyright}"
586 classpathref="lib.classpath">
587 <fileset dir="${src.dir}" includes="**/*.java"/>
588 <arg value="-tag"/>
589 <arg value="pre:a:Precondition:"/>
521590 </javadoc>
522591 </target>
523
524 <target name="sources" depends="default-version" description="Create source archive files">
525 <mkdir dir="${artifacts.build.dir}/sources/"/>
526 <jar destfile="${artifacts.build.dir}/sources/${final.name}">
527 <metainf dir="${basedir}" includes="LICENSE,NOTICE" />
528 <manifest>
529 <attribute name="Specification-Title" value="Apache Ivy Sources" />
530 <attribute name="Specification-Version" value="${build.version}" />
531 <attribute name="Specification-Vendor" value="Apache Software Foundation" />
532 </manifest>
533 <fileset dir="${src.dir}" />
534 </jar>
535 </target>
536
537 <target name="fixcrlf">
538 <property name="eol.native.includes"
539 value="**/*.html,**/*.json,**/*.java,**/*.xml,**/*.txt,**/*.MF,**/*.properties,**/*.patterns,**/*.pom,**/*.xsl,**/*.css" />
540 <property name="eol.native.excludes"
541 value="build/**,bin/**,lib/**" />
542
543 <fileset id="eol.native.fileset"
544 dir="${basedir}"
545 includes="${eol.native.includes}"
546 excludes="${eol.native.excludes}" />
547
548 <fixcrlf srcdir="${basedir}"
549 includes="${eol.native.includes}"
550 excludes="${eol.native.excludes}" />
551 <apply executable="svn">
552 <fileset refid="eol.native.fileset" />
553 <arg value="propset" />
554 <arg value="svn:eol-style" />
555 <arg value='"native"' />
556 </apply>
557 </target>
558
592
593 <target name="javadoc-test" depends="init" unless="skip.javadoc">
594 <tstamp>
595 <format pattern="2007-yyyy" property="years"/>
596 </tstamp>
597 <property name="copyright" value="Copyright &amp;copy;${years} The Apache Software Foundation, Licensed under &lt;a href=&quot;https://www.apache.org/licenses/LICENSE-2.0.txt&quot;&gt;Apache License, Version 2.0&lt;/a&gt;."/>
598 <property name="title" value="Apache Ivy&amp;trade; dependency manager ${target.ivy.version} API"/>
599 <javadoc destdir="${test.javadoc.build.dir}"
600 useexternalfile="true"
601 windowtitle="Apache Ivy&amp;trade;"
602 doctitle="${title}"
603 bottom="${copyright}"
604 classpathref="javadoc.test.classpath">
605 <fileset dir="${test.dir}" includes="**/*.java"/>
606 </javadoc>
607 </target>
608
609 <target name="init-checkstyle" depends="jar">
610 <ivy:cachepath organisation="com.puppycrawl.tools" module="checkstyle" revision="6.19"
611 inline="true" conf="default" pathid="checkstyle.classpath" log="download-only"/>
612 <taskdef uri="antlib:com.puppycrawl.tools.checkstyle.ant"
613 resource="com/puppycrawl/tools/checkstyle/ant/antlib.xml" classpathref="checkstyle.classpath"/>
614 </target>
615
559616 <!-- Checks Ivy codebase according to ${checkstyle.src.dir}/checkstyle-config -->
560 <target name="checkstyle-internal" depends="jar">
561 <ivy:cachepath organisation="checkstyle" module="checkstyle" revision="5.0"
562 inline="true" conf="default" pathid="checkstyle.classpath" transitive="true"
563 log="download-only"/>
564 <taskdef resource="checkstyletask.properties" classpathref="checkstyle.classpath" />
565
566 <mkdir dir="${checkstyle.report.dir}" />
567 <checkstyle config="${checkstyle.src.dir}/checkstyle-config"
568 failOnViolation="false" failureProperty="checkstyle.failed">
569 <classpath>
570 <path refid="run.classpath" />
571 </classpath>
572 <formatter type="xml" toFile="${checkstyle.report.dir}/checkstyle.xml" />
617 <target name="checkstyle-internal" depends="init-checkstyle">
618 <mkdir dir="${checkstyle.report.dir}"/>
619 <cs:checkstyle xmlns:cs="antlib:com.puppycrawl.tools.checkstyle.ant"
620 config="${checkstyle.src.dir}/checkstyle-config"
621 failOnViolation="false" failureProperty="checkstyle.failed">
622 <classpath>
623 <path refid="run.classpath"/>
624 </classpath>
625 <formatter type="xml" toFile="${checkstyle.report.dir}/checkstyle.xml"/>
573626 <fileset dir="${src.dir}">
574 <include name="**/*.java" />
627 <include name="**/*.java"/>
575628 </fileset>
576629 <fileset dir="${example.dir}">
577 <include name="**/*.java" />
578 </fileset>
579 </checkstyle>
580 </target>
581
582 <target name="checkstyle" depends="checkstyle-internal" description="checks Ivy codebase according to ${checkstyle.src.dir}/checkstyle-config">
583 <fail if="checkstyle.failed"
584 message="Checkstyle has errors. See report in ${checkstyle.report.dir}" />
630 <include name="**/*.java"/>
631 </fileset>
632 </cs:checkstyle>
633 </target>
634
635 <target name="checkstyle" depends="checkstyle-internal"
636 description="checks Ivy codebase according to ${checkstyle.src.dir}/checkstyle-config">
637 <fail if="checkstyle.failed" unless="ignore.checkstyle"
638 message="Checkstyle has errors. See report in ${checkstyle.report.dir}"/>
585639 </target>
586640
587641 <target name="checkstyle-report" depends="checkstyle-internal">
588 <property name="checkstyle.basedir" location="${src.dir}" />
642 <property name="checkstyle.basedir" location="${src.dir}"/>
589643 <xslt in="${checkstyle.report.dir}/checkstyle.xml"
590 style="${checkstyle.src.dir}/checkstyle-frames.xsl"
591 out="${checkstyle.report.dir}/output.txt">
592 <param name="basedir" expression="${checkstyle.basedir}" />
644 style="${checkstyle.src.dir}/checkstyle-frames.xsl"
645 out="${checkstyle.report.dir}/output.txt">
646 <param name="basedir" expression="${checkstyle.basedir}"/>
647 <param name="output.dir" expression="${checkstyle.report.dir}"/>
593648 </xslt>
594649 </target>
595650
596651 <target name="init-findbugs" unless="findbugs.home">
597 <!-- Findbugs: Getting Findbugs -->
598 <property name="findbugs.download.name"
599 value="findbugs-1.3.5"
652 <!-- Findbugs: Getting Findbugs requires unlimited strength crypto policy -->
653 <property name="findbugs.version"
654 value="3.0.1"
655 description="Version of Findbugs to use"/>
656 <property name="findbugs.download.name"
657 value="findbugs-${findbugs.version}"
600658 description="Name of the download file without suffix. Also the internal root directory of the ZIP."/>
601 <property name="findbugs.download.file"
659 <property name="findbugs.download.file"
602660 value="${findbugs.download.name}.zip"
603661 description="The filename of the ZIP."/>
604 <property name="findbugs.download.url"
605 value="http://garr.dl.sourceforge.net/sourceforge/findbugs/${findbugs.download.file}"
662 <property name="findbugs.download.url"
663 value="https://downloads.sourceforge.net/project/findbugs/findbugs/${findbugs.version}/findbugs-${findbugs.version}.zip"
606664 description="The download adress at a mirror of Sourceforge."/>
607 <property name="findbugs.download.to"
665 <property name="findbugs.download.to"
608666 value="${build.dir}/.downloads"
609667 description="Where to store the download and 'install' Findbugs."/>
610 <available
611 property="findbugs.home"
612 value="${findbugs.download.to}/${findbugs.download.name}"
613 file="${findbugs.download.to}/${findbugs.download.name}/lib/findbugs.jar"
614 description="Check if Findbugs is already installed."
615 />
616
668 <available property="findbugs.home"
669 value="${findbugs.download.to}/${findbugs.download.name}"
670 file="${findbugs.download.to}/${findbugs.download.name}/lib/findbugs.jar"
671 description="Check if Findbugs is already installed."/>
672
617673 <!-- Findbugs: Running Findbugs -->
618 <property name="findbugs.reportdir"
619 location="${reports.dir}/findbugs"
674 <property name="findbugs.reportdir"
675 location="${reports.dir}/findbugs"
620676 description="Where to store Findbugs results"/>
621 <property name="findbugs.raw"
622 value="raw.xml"
623 description="Findbugs Output xml-file"/>
624 <property name="findbugs.xsl"
625 value="fancy.xsl"
626 description="Which XSL to use for generating Output: default, fancy, plain, summary"/>
627 <property name="findbugs.jvmargs"
628 value="-Xms128m -Xmx512m"
677 <property name="findbugs.raw"
678 value="raw.xml"
679 description="Findbugs output xml file"/>
680 <property name="findbugs.xsl"
681 value="fancy.xsl"
682 description="Which XSL to use for generating output: default, fancy, plain, summary"/>
683 <property name="findbugs.jvmargs"
684 value="-Xms128m -Xmx512m"
629685 description="JVMArgs for invoking Findbugs"/>
630686
631687 <mkdir dir="${findbugs.download.to}"/>
632 <get src="${findbugs.download.url}" dest="${findbugs.download.to}/${findbugs.download.file}"/>
688 <get src="${findbugs.download.url}" dest="${findbugs.download.to}/${findbugs.download.file}"
689 usetimestamp="true" skipexisting="true"/>
633690 <unzip src="${findbugs.download.to}/${findbugs.download.file}" dest="${findbugs.download.to}"/>
634691 <property name="findbugs.home" location="${findbugs.download.to}/${findbugs.download.name}"/>
635 <mkdir dir="${findbugs.home}/plugin"/>
636 </target>
637
692 </target>
693
638694 <target name="findbugs" description="checks Ivy codebase with Findbugs" depends="init-findbugs,compile-core" xmlns:fb="http://findbugs.sourceforge.net/">
695 <!-- Load the Findbugs AntTasks -->
639696 <path id="findbugs.real.classpath">
640 <fileset dir="${findbugs.home}/lib" includes="*.jar"/>
697 <fileset dir="${findbugs.home}/lib" includes="*.jar"/>
641698 </path>
642
643 <!-- Load the Findbugs AntTasks -->
644 <taskdef uri="http://findbugs.sourceforge.net/" resource="edu/umd/cs/findbugs/anttask/tasks.properties" classpathref="findbugs.real.classpath" />
645
699 <taskdef uri="http://findbugs.sourceforge.net/" resource="edu/umd/cs/findbugs/anttask/tasks.properties" classpathref="findbugs.real.classpath"/>
700
646701 <!-- Start Findbugs -->
647702 <mkdir dir="${findbugs.reportdir}"/>
648703 <fb:findbugs home="${findbugs.home}"
650705 output="xml:withMessages"
651706 outputFile="${findbugs.reportdir}/${findbugs.raw}"
652707 jvmargs="${findbugs.jvmargs}"
653 projectName="${Name} ${project.version}">
654 <class location="${core.classes.build.dir}" />
655 <sourcePath path="${src.dir}" />
708 projectName="${ant.project.name} ${target.ivy.version}">
709 <class location="${core.classes.build.dir}"/>
710 <sourcePath path="${src.dir}"/>
656711 </fb:findbugs>
657
712
658713 <!-- Generate (human) readable output -->
659714 <xslt basedir="${findbugs.reportdir}" includes="${findbugs.raw}" destdir="${findbugs.reportdir}">
660715 <style>
661716 <javaresource name="${findbugs.xsl}" classpathref="findbugs.real.classpath"/>
662 </style>
717 </style>
663718 </xslt>
664719 </target>
665
720
721 <target name="docs" depends="test-report,checkstyle-report,findbugs,japicmp,ivy-report,javadoc"/>
722
666723 <!-- =================================================================
667724 IDE SPECIFIC
668725 ================================================================= -->
669 <available file="${basedir}/.classpath" property="eclipse.classpath.exists" />
726 <available file="${basedir}/.classpath" property="eclipse.classpath.exists"/>
670727 <target name="check-eclipse-classpath-overwrite" if="eclipse.classpath.exists">
671 <input message=".classpath file already exists.${line.separator}Are you sure you want to overwrite it and loose your original file?"
672 validargs="Y,N,y,n" addproperty="eclipse.classpath.confirm" />
728 <input message=".classpath file already exists.${line.separator}Are you sure you want to overwrite it and loose your original file?"
729 validargs="Y,N,y,n" addproperty="eclipse.classpath.confirm"/>
673730 <condition property="eclipse.classpath.abort">
674 <equals arg1="${eclipse.classpath.confirm}" arg2="N" casesensitive="false" />
731 <equals arg1="${eclipse.classpath.confirm}" arg2="N" casesensitive="false"/>
675732 </condition>
676733 </target>
677
678 <target name="eclipse-default" depends="resolve, check-eclipse-classpath-overwrite"
734
735 <target name="eclipse-default" depends="resolve,check-eclipse-classpath-overwrite"
679736 unless="eclipse.classpath.abort"
680 description="creates a default .classpath for eclipse, using jars resolved by this ant build">
681 <copy file="${basedir}/.classpath.default" tofile="${basedir}/.classpath" overwrite="true" />
737 description="creates a default .classpath for Eclipse using jars resolved by this Ant build">
738 <copy file="${basedir}/.classpath.default" tofile="${basedir}/.classpath" overwrite="true"/>
682739 </target>
683740
684741 <target name="eclipse-ivyde" depends="check-eclipse-classpath-overwrite"
685742 unless="eclipse.classpath.abort"
686 description="creates a .classpath for eclipse using Apache IvyDE version">
687 <copy file="${basedir}/.classpath.ivyde" tofile="${basedir}/.classpath" overwrite="true" />
743 description="creates a .classpath for Eclipse using Apache IvyDE plugin">
744 <copy file="${basedir}/.classpath.ivyde" tofile="${basedir}/.classpath" overwrite="true"/>
688745 </target>
689746 </project>
0 <?xml version="1.0"?>
1 <?xml-stylesheet type="text/xsl"?>
2 <!--
3 Licensed to the Apache Software Foundation (ASF) under one or more
4 contributor license agreements. See the NOTICE file distributed with
5 this work for additional information regarding copyright ownership.
6 The ASF licenses this file to You under the Apache License, Version 2.0
7 (the "License"); you may not use this file except in compliance with
8 the License. You may obtain a copy of the License at
9
10 https://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 -->
18 <rdf:RDF xml:lang="en"
19 xmlns="http://usefulinc.com/ns/doap#"
20 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
21 xmlns:asfext="http://projects.apache.org/ns/asfext#"
22 xmlns:foaf="http://xmlns.com/foaf/0.1/">
23 <Project rdf:about="http://ant.apache.org/ivy/">
24 <created>2010-11-16</created>
25 <license rdf:resource="http://usefulinc.com/doap/licenses/asl20" />
26 <name>Apache Ivy</name>
27 <homepage rdf:resource="http://ant.apache.org/ivy/" />
28 <asfext:pmc rdf:resource="http://ant.apache.org" />
29 <shortdesc>Apache Ivy is a very powerful dependency manager oriented toward Java dependency management, even though it could be used to manage dependencies of any kind.</shortdesc>
30 <description>Apache Ivy is a very powerful dependency manager oriented toward Java dependency management, even though it could be used to manage dependencies of any kind.</description>
31 <bug-database rdf:resource="https://issues.apache.org/jira/browse/IVY" />
32 <mailing-list rdf:resource="http://ant.apache.org/ivy/mailing-lists.html" />
33 <download-page rdf:resource="http://ant.apache.org/ivy/download.cgi" />
34 <programming-language>Java</programming-language>
35 <category rdf:resource="http://projects.apache.org/category/build-management" />
36 <release>
37 <Version>
38 <name>Apache Ivy 2.4.0</name>
39 <created>2014-12-26</created>
40 <revision>2.4.0</revision>
41 </Version>
42 </release>
43 <release>
44 <Version>
45 <name>Apache Ivy 2.3.0</name>
46 <created>2013-01-24</created>
47 <revision>2.3.0</revision>
48 </Version>
49 </release>
50 <release>
51 <Version>
52 <name>Apache Ivy 2.2.0</name>
53 <created>2010-10-07</created>
54 <revision>2.2.0</revision>
55 </Version>
56 </release>
57 <release>
58 <Version>
59 <name>Apache Ivy 2.1.0</name>
60 <created>2009-10-13</created>
61 <revision>2.1.0</revision>
62 </Version>
63 </release>
64 <release>
65 <Version>
66 <name>Apache Ivy 2.0.0</name>
67 <created>2009-01-22</created>
68 <revision>2.0.0</revision>
69 </Version>
70 </release>
71 <repository>
72 <GitRepository>
73 <location rdf:resource="https://gitbox.apache.org/repos/asf/ant-ivy.git"/>
74 <browse rdf:resource="https://gitbox.apache.org/repos/asf?p=ant-ivy.git"/>
75 </GitRepository>
76 </repository>
77 </Project>
78 </rdf:RDF>
0 <?xml version="1.0" encoding="UTF-8"?>
10 <!--
21 Licensed to the Apache Software Foundation (ASF) under one
32 or more contributor license agreements. See the NOTICE file
76 "License"); you may not use this file except in compliance
87 with the License. You may obtain a copy of the License at
98
10 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1110
1211 Unless required by applicable law or agreed to in writing,
1312 software distributed under the License is distributed on an
1615 specific language governing permissions and limitations
1716 under the License.
1817 -->
19 <ivy-module version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
20 <info organisation="org.apache.ivy" module="ivy" revision="2.4.0" status="release" publication="20141213170938">
21 <description homepage="http://ant.apache.org/ivy/">
22 Apache Ivy is a tool for managing (recording, tracking, resolving and reporting) project dependencies.
23 </description>
24 </info>
25 <configurations>
26 <conf name="core" description="only ivy jar, without any dependencies"/>
27 <conf name="httpclient" extends="core" description="core + optional httpclient for better http handling"/>
28 <conf name="oro" extends="core" description="to use optional glob matcher"/>
29 <conf name="vfs" extends="core" description="core + optional VirtualFileSystem(VFS) support"/>
30 <conf name="sftp" extends="core" description="core + optional SFTP support"/>
31 <conf name="standalone" extends="core" description="to launch in standalone mode (from command line)"/>
32 <conf name="ant" extends="core" description="core + ant jar provided as a dependency"/>
33 <conf name="default" extends="core" description="full ivy with all dependencies"/>
34 <conf name="test" description="dependencies used for junit testing ivy" visibility="private"/>
35 <conf name="source" description="ivy sources"/>
36 </configurations>
37 <publications>
38 <artifact name="ivy" type="jar" conf="core"/>
39 <artifact name="ivy" type="source" ext="jar" conf="source"/>
40 </publications>
41 <dependencies>
42 <dependency org="org.apache.ant" name="ant" rev="1.7.1" conf="default,ant->default"/>
43 <dependency org="org.apache.ant" name="ant-nodeps" rev="1.7.1" conf="default"/>
44 <dependency org="org.apache.ant" name="ant-trax" rev="1.7.1" conf="default"/>
45 <dependency org="commons-httpclient" name="commons-httpclient" rev="3.0" conf="default,httpclient->runtime,master"/>
46 <dependency org="oro" name="oro" rev="2.0.8" conf="default,oro->default"/>
47 <dependency org="commons-vfs" name="commons-vfs" rev="1.0" conf="default,vfs->default"/>
48 <dependency org="com.jcraft" name="jsch" rev="0.1.50" conf="default,sftp->default"/>
49 <dependency org="com.jcraft" name="jsch.agentproxy" rev="0.0.6" conf="default,sftp->default"/>
50 <dependency org="com.jcraft" name="jsch.agentproxy.connector-factory" rev="0.0.6" conf="default,sftp->default"/>
51 <dependency org="com.jcraft" name="jsch.agentproxy.jsch" rev="0.0.6" conf="default,sftp->default"/>
52 <dependency org="org.bouncycastle" name="bcpg-jdk14" rev="1.45" conf="default"/>
53 <dependency org="org.bouncycastle" name="bcprov-jdk14" rev="1.45" conf="default"/>
18 <ivy-module version="1.0"
19 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
20 xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
21 <info organisation="org.apache.ivy"
22 module="ivy"
23 status="release">
24 <description homepage="http://ant.apache.org/ivy/">
25 Apache Ivy is a tool for managing (recording, tracking, resolving and reporting) project dependencies.
26 </description>
27 </info>
28 <configurations defaultconfmapping="*->default">
29 <conf name="core" description="only ivy jar, without any dependencies"/>
30 <conf name="httpclient" extends="core" description="core + optional httpclient for better http handling"/>
31 <conf name="oro" extends="core" description="to use optional glob matcher"/>
32 <conf name="vfs" extends="core" description="core + optional VirtualFileSystem(VFS) support" />
33 <conf name="sftp" extends="core" description="core + optional SFTP support" />
34 <conf name="standalone" extends="core" description="to launch in standalone mode (from command line)"/>
35 <conf name="ant" extends="core" description="core + ant jar provided as a dependency"/>
36 <conf name="default" extends="core" description="full ivy with all dependencies"/>
37 <conf name="test" description="dependencies used for junit testing ivy" visibility="private"/>
38 <conf name="source" description="ivy sources"/>
39 </configurations>
40 <publications>
41 <artifact name="ivy" type="jar" conf="core"/>
42 <artifact name="ivy" type="source" ext="jar" conf="source"/>
43 </publications>
44 <!-- Definition of the version is done in version.properties -->
45 <dependencies>
46 <dependency org="org.apache.ant" name="ant" rev="${apache-ant.version}" conf="default,ant"/>
47 <dependency org="org.apache.httpcomponents" name="httpclient" rev="${httpclient.version}" conf="default,httpclient->runtime,master"/>
48 <dependency org="oro" name="oro" rev="${oro.version}" conf="default,oro"/>
49 <dependency org="org.apache.commons" name="commons-vfs2" rev="${commons-vfs2.version}" conf="default,vfs"/>
50 <dependency org="com.jcraft" name="jsch" rev="${jsch.version}" conf="default,sftp"/>
51 <dependency org="com.jcraft" name="jsch.agentproxy" rev="${jsch.agentproxy.version}" conf="default,sftp"/>
52 <dependency org="com.jcraft" name="jsch.agentproxy.connector-factory" rev="${jsch.agentproxy.version}" conf="default,sftp"/>
53 <dependency org="com.jcraft" name="jsch.agentproxy.jsch" rev="${jsch.agentproxy.version}" conf="default,sftp"/>
54 <dependency org="org.bouncycastle" name="bcpg-jdk15on" rev="${bouncycastle.version}" conf="default"/>
55 <dependency org="org.bouncycastle" name="bcprov-jdk15on" rev="${bouncycastle.version}" conf="default"/>
5456
55 <!-- Test dependencies -->
56 <dependency org="junit" name="junit" rev="3.8.2" conf="test->default"/>
57 <dependency org="commons-lang" name="commons-lang" rev="2.6" conf="test->default"/>
58 <dependency org="org.apache.ant" name="ant-testutil" rev="1.7.0" conf="test->default" transitive="false"/>
59 <dependency org="ant" name="ant-launcher" rev="1.6.2" conf="test->default" transitive="false"/>
60 <dependency org="ant-contrib" name="ant-contrib" rev="1.0b3" conf="test->default" transitive="false"/>
61
62 <!-- This dependency is necessary for having validation in junit tests when running with JDK1.4 -->
63 <dependency org="xerces" name="xercesImpl" rev="2.6.2" conf="test->default"/>
64 <dependency org="xerces" name="xmlParserAPIs" rev="2.6.2" conf="test->default"/>
57 <!-- Test dependencies -->
58 <dependency org="junit" name="junit" rev="${junit.version}" conf="test"/>
59 <dependency org="org.hamcrest" name="hamcrest-core" rev="${hamcrest.version}" conf="test"/>
60 <dependency org="org.hamcrest" name="hamcrest-library" rev="${hamcrest.version}" conf="test"/>
61 <dependency org="org.apache.ant" name="ant-testutil" rev="${apache-ant.version}" conf="test" transitive="false"/>
62 <dependency org="org.apache.ant" name="ant-launcher" rev="${apache-ant.version}" conf="test" transitive="false"/>
63 <dependency org="org.apache.ant" name="ant-junit" rev="${apache-ant.version}" conf="test" transitive="false"/>
64 <dependency org="org.apache.ant" name="ant-junit4" rev="${apache-ant.version}" conf="test" transitive="false"/>
65 <dependency org="ant-contrib" name="ant-contrib" rev="${ant-contrib.version}" conf="test" transitive="false"/>
66 <dependency org="xmlunit" name="xmlunit" rev="${xmlunit.version}" conf="test" transitive="false"/>
6567
66 <!-- Global exclude for junit -->
67 <exclude org="junit" module="junit" conf="core,default,httpclient,oro,vfs,sftp,standalone,ant"/>
68 </dependencies>
68 <!-- Global excludes -->
69 <exclude org="junit" module="junit" conf="core,default,httpclient,oro,vfs,sftp,standalone,ant"/>
70 <exclude org="org.hamcrest" module="hamcrest-core" conf="core,default,httpclient,oro,vfs,sftp,standalone,ant"/>
71 <!-- Exclude the whole outdated commons-httpclient org -->
72 <exclude org="commons-httpclient" conf="*"/>
73 </dependencies>
6974 </ivy-module>
+0
-291
ivy.xsd less more
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!--
2 Licensed to the Apache Software Foundation (ASF) under one
3 or more contributor license agreements. See the NOTICE file
4 distributed with this work for additional information
5 regarding copyright ownership. The ASF licenses this file
6 to you under the Apache License, Version 2.0 (the
7 "License"); you may not use this file except in compliance
8 with the License. You may obtain a copy of the License at
9
10 http://www.apache.org/licenses/LICENSE-2.0
11
12 Unless required by applicable law or agreed to in writing,
13 software distributed under the License is distributed on an
14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 KIND, either express or implied. See the License for the
16 specific language governing permissions and limitations
17 under the License.
18 -->
19 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
20
21 <xs:complexType name="configurations-conf">
22 <xs:attribute name="name" type="xs:string" use="required"/>
23 <xs:attribute name="transitive" type="xs:boolean"/>
24 <xs:attribute name="extends" type="xs:string"/>
25 <xs:attribute name="description" type="xs:string"/>
26 <xs:attribute name="deprecated" type="xs:string"/>
27 <xs:attribute name="visibility" default="public">
28 <xs:simpleType>
29 <xs:restriction base="xs:string">
30 <xs:enumeration value="private"/>
31 <xs:enumeration value="public"/>
32 </xs:restriction>
33 </xs:simpleType>
34 </xs:attribute>
35 <xs:anyAttribute namespace="##other" processContents="lax" />
36 </xs:complexType>
37
38 <xs:complexType name="global-exclude">
39 <xs:sequence>
40 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
41 <xs:complexType>
42 <xs:attribute name="name" type="xs:string" use="required"/>
43 </xs:complexType>
44 </xs:element>
45 </xs:sequence>
46 <xs:attribute name="org" type="xs:string"/>
47 <xs:attribute name="module" type="xs:string"/>
48 <xs:attribute name="artifact" type="xs:string"/>
49 <xs:attribute name="type" type="xs:string"/>
50 <xs:attribute name="ext" type="xs:string"/>
51 <xs:attribute name="conf" type="xs:string"/>
52 <xs:attribute name="matcher" type="xs:string"/>
53 <xs:anyAttribute namespace="##other" processContents="lax" />
54 </xs:complexType>
55
56 <xs:element name="ivy-module">
57 <xs:complexType>
58 <xs:sequence>
59 <xs:element name="info">
60 <xs:complexType>
61 <xs:sequence>
62 <xs:element name="extends" minOccurs="0" maxOccurs="unbounded">
63 <xs:complexType>
64 <xs:attribute name="organisation" type="xs:string" use="required"/>
65 <xs:attribute name="module" type="xs:string" use="required"/>
66 <xs:attribute name="revision" type="xs:string" use="required"/>
67 <xs:attribute name="location" type="xs:string" />
68 <xs:attribute name="extendType" type="xs:string" />
69 </xs:complexType>
70 </xs:element>
71 <xs:element name="license" minOccurs="0" maxOccurs="unbounded">
72 <xs:complexType>
73 <xs:attribute name="name" type="xs:string" use="required"/>
74 <xs:attribute name="url" type="xs:string"/>
75 </xs:complexType>
76 </xs:element>
77 <xs:element name="ivyauthor" minOccurs="0" maxOccurs="unbounded">
78 <xs:complexType>
79 <xs:attribute name="name" type="xs:string" use="required"/>
80 <xs:attribute name="url" type="xs:string"/>
81 </xs:complexType>
82 </xs:element>
83 <xs:element name="repository" minOccurs="0" maxOccurs="unbounded">
84 <xs:complexType>
85 <xs:attribute name="name" type="xs:string" use="required"/>
86 <xs:attribute name="url" type="xs:string"/>
87 <xs:attribute name="pattern" type="xs:string"/>
88 <xs:attribute name="ivys" type="xs:boolean"/>
89 <xs:attribute name="artifacts" type="xs:boolean"/>
90 </xs:complexType>
91 </xs:element>
92 <xs:element name="description" minOccurs="0" maxOccurs="1">
93 <xs:complexType mixed="true">
94 <xs:sequence>
95 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
96 </xs:sequence>
97 <xs:attribute name="homepage" type="xs:string"/>
98 </xs:complexType>
99 </xs:element>
100 <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="lax"/>
101 </xs:sequence>
102 <xs:attribute name="organisation" type="xs:string"/>
103 <xs:attribute name="module" type="xs:string" use="required"/>
104 <xs:attribute name="branch" type="xs:string"/>
105 <xs:attribute name="revision" type="xs:string"/>
106 <xs:attribute name="status" type="xs:string"/>
107 <xs:attribute name="publication" type="xs:string"/>
108 <xs:attribute name="resolver" type="xs:string"/>
109 <xs:attribute name="namespace" type="xs:string"/>
110 <xs:attribute name="default" type="xs:boolean"/>
111 <xs:anyAttribute namespace="##other" processContents="lax" />
112 </xs:complexType>
113 </xs:element>
114 <xs:element name="configurations" minOccurs="0">
115 <xs:complexType>
116 <xs:sequence>
117 <xs:choice minOccurs="0" maxOccurs="unbounded">
118 <xs:element name="conf" type="configurations-conf"/>
119 <xs:element name="include">
120 <xs:complexType>
121 <xs:attribute name="file" type="xs:string"/>
122 <xs:attribute name="url" type="xs:string"/>
123 </xs:complexType>
124 </xs:element>
125 </xs:choice>
126 </xs:sequence>
127 <xs:attribute name="defaultconf" type="xs:string"/>
128 <xs:attribute name="defaultconfmapping" type="xs:string"/>
129 <xs:attribute name="confmappingoverride" type="xs:boolean" />
130 </xs:complexType>
131 </xs:element>
132 <xs:element name="publications" minOccurs="0">
133 <xs:complexType>
134 <xs:sequence>
135 <xs:element name="artifact" minOccurs="0" maxOccurs="unbounded">
136 <xs:complexType>
137 <xs:sequence>
138 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
139 <xs:complexType>
140 <xs:attribute name="name" type="xs:string" use="required"/>
141 </xs:complexType>
142 </xs:element>
143 </xs:sequence>
144 <xs:attribute name="name" type="xs:string"/>
145 <xs:attribute name="type" type="xs:string"/>
146 <xs:attribute name="ext" type="xs:string"/>
147 <xs:attribute name="conf" type="xs:string"/>
148 <xs:attribute name="url" type="xs:string"/>
149 <xs:attribute name="packaging" type="xs:string"/>
150 <xs:anyAttribute namespace="##other" processContents="lax" />
151 </xs:complexType>
152 </xs:element>
153 </xs:sequence>
154 <xs:attribute name="defaultconf" type="xs:string"/>
155 </xs:complexType>
156 </xs:element>
157 <xs:element name="dependencies" minOccurs="0">
158 <xs:complexType>
159 <xs:sequence>
160 <xs:element name="dependency" minOccurs="0" maxOccurs="unbounded">
161 <xs:complexType>
162 <xs:sequence>
163 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
164 <xs:complexType>
165 <xs:sequence>
166 <xs:element name="mapped" minOccurs="0" maxOccurs="unbounded">
167 <xs:complexType>
168 <xs:attribute name="name" type="xs:string" use="required"/>
169 </xs:complexType>
170 </xs:element>
171 </xs:sequence>
172 <xs:attribute name="name" type="xs:string" use="required"/>
173 <xs:attribute name="mapped" type="xs:string"/>
174 </xs:complexType>
175 </xs:element>
176 <xs:element name="artifact" minOccurs="0" maxOccurs="unbounded">
177 <xs:complexType>
178 <xs:sequence>
179 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
180 <xs:complexType>
181 <xs:attribute name="name" type="xs:string" use="required"/>
182 </xs:complexType>
183 </xs:element>
184 </xs:sequence>
185 <xs:attribute name="name" type="xs:string" use="required"/>
186 <xs:attribute name="type" type="xs:string"/>
187 <xs:attribute name="ext" type="xs:string"/>
188 <xs:attribute name="conf" type="xs:string"/>
189 <xs:attribute name="url" type="xs:string"/>
190 <xs:anyAttribute namespace="##other" processContents="lax" />
191 </xs:complexType>
192 </xs:element>
193 <xs:element name="include" minOccurs="0" maxOccurs="unbounded">
194 <xs:complexType>
195 <xs:sequence>
196 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
197 <xs:complexType>
198 <xs:attribute name="name" type="xs:string" use="required"/>
199 </xs:complexType>
200 </xs:element>
201 </xs:sequence>
202 <xs:attribute name="name" type="xs:string"/>
203 <xs:attribute name="type" type="xs:string"/>
204 <xs:attribute name="ext" type="xs:string"/>
205 <xs:attribute name="conf" type="xs:string"/>
206 <xs:attribute name="matcher" type="xs:string"/>
207 <xs:anyAttribute namespace="##other" processContents="lax" />
208 </xs:complexType>
209 </xs:element>
210 <xs:element name="exclude" minOccurs="0" maxOccurs="unbounded">
211 <xs:complexType>
212 <xs:sequence>
213 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
214 <xs:complexType>
215 <xs:attribute name="name" type="xs:string" use="required"/>
216 </xs:complexType>
217 </xs:element>
218 </xs:sequence>
219 <xs:attribute name="org" type="xs:string"/>
220 <xs:attribute name="module" type="xs:string"/>
221 <xs:attribute name="name" type="xs:string"/>
222 <xs:attribute name="type" type="xs:string"/>
223 <xs:attribute name="ext" type="xs:string"/>
224 <xs:attribute name="conf" type="xs:string"/>
225 <xs:attribute name="matcher" type="xs:string"/>
226 <xs:anyAttribute namespace="##other" processContents="lax" />
227 </xs:complexType>
228 </xs:element>
229 </xs:sequence>
230 <xs:attribute name="org" type="xs:string"/>
231 <xs:attribute name="name" type="xs:string" use="required"/>
232 <xs:attribute name="branch" type="xs:string"/>
233 <xs:attribute name="branchConstraint" type="xs:string"/>
234 <xs:attribute name="rev" type="xs:string" use="required"/>
235 <xs:attribute name="revConstraint" type="xs:string"/>
236 <xs:attribute name="force" type="xs:boolean"/>
237 <xs:attribute name="changing" type="xs:boolean" default="false"/>
238 <xs:attribute name="transitive" type="xs:boolean" default="true"/>
239 <xs:attribute name="conf" type="xs:string"/>
240 <xs:anyAttribute namespace="##other" processContents="lax" />
241 </xs:complexType>
242 </xs:element>
243 <xs:element name="exclude" type="global-exclude" minOccurs="0" maxOccurs="unbounded" />
244 <xs:element name="override" minOccurs="0" maxOccurs="unbounded">
245 <xs:complexType>
246 <xs:attribute name="org" type="xs:string"/>
247 <xs:attribute name="module" type="xs:string"/>
248 <xs:attribute name="matcher" type="xs:string"/>
249 <xs:attribute name="rev" type="xs:string"/>
250 <xs:attribute name="branch" type="xs:string"/>
251 </xs:complexType>
252 </xs:element>
253 <xs:element name="conflict" minOccurs="0" maxOccurs="unbounded">
254 <xs:complexType>
255 <xs:attribute name="org" type="xs:string"/>
256 <xs:attribute name="module" type="xs:string"/>
257 <xs:attribute name="manager" type="xs:string"/>
258 <xs:attribute name="rev" type="xs:string"/>
259 <xs:attribute name="matcher" type="xs:string"/>
260 <xs:anyAttribute namespace="##other" processContents="lax" />
261 </xs:complexType>
262 </xs:element>
263 </xs:sequence>
264 <xs:attribute name="defaultconf" type="xs:string"/>
265 <xs:attribute name="defaultconfmapping" type="xs:string"/>
266 <xs:attribute name="confmappingoverride" type="xs:boolean" />
267 </xs:complexType>
268 </xs:element>
269 <xs:element name="conflicts" minOccurs="0">
270 <xs:complexType>
271 <xs:sequence>
272 <xs:element name="manager" maxOccurs="unbounded">
273 <xs:complexType>
274 <xs:attribute name="org" type="xs:string"/>
275 <xs:attribute name="module" type="xs:string"/>
276 <xs:attribute name="name" type="xs:string"/>
277 <xs:attribute name="rev" type="xs:string"/>
278 <xs:attribute name="matcher" type="xs:string"/>
279 <xs:anyAttribute namespace="##other" processContents="lax" />
280 </xs:complexType>
281 </xs:element>
282 </xs:sequence>
283 </xs:complexType>
284 </xs:element>
285 </xs:sequence>
286 <xs:attribute name="version" type="xs:string" use="required"/>
287 </xs:complexType>
288 </xs:element>
289
290 </xs:schema>
0 <!--
1 Licensed to the Apache Software Foundation (ASF) under one
2 or more contributor license agreements. See the NOTICE file
3 distributed with this work for additional information
4 regarding copyright ownership. The ASF licenses this file
5 to you under the Apache License, Version 2.0 (the
6 "License"); you may not use this file except in compliance
7 with the License. You may obtain a copy of the License at
8
9 https://www.apache.org/licenses/LICENSE-2.0
10
11 Unless required by applicable law or agreed to in writing,
12 software distributed under the License is distributed on an
13 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 KIND, either express or implied. See the License for the
15 specific language governing permissions and limitations
16 under the License.
17 -->
18 <ivysettings>
19 <property name="upload.url" value="https://repository.apache.org/service/local/staging/deploy/maven2" />
20 <property name="pgp.keyId" value="auto" override="false" />
21 <credentials host="repository.apache.org" realm="Sonatype Nexus Repository Manager" username="${upload.user}" passwd="${upload.password}"/>
22
23 <signers>
24 <pgp name="apache-sig" secring="${user.home}/.gnupg/secring.gpg" password="${pgp.password}" keyId="${pgp.keyId}"/>
25 </signers>
26
27 <settings defaultResolver="default" />
28 <resolvers>
29 <chain name="default">
30 <ibiblio name="public" m2compatible="true" />
31 <ibiblio name="snapshot" m2compatible="true" root="https://repository.apache.org/content/repositories/snapshots/" />
32 </chain>
33 <url name="nexus" m2compatible="true" signer="apache-sig">
34 <artifact pattern="${upload.url}/[organisation]/[module]/[revision]/[artifact]-[revision](-[classifier]).[ext]" />
35 </url>
36 </resolvers>
37 </ivysettings>
66 # * "License"); you may not use this file except in compliance
77 # * with the License. You may obtain a copy of the License at
88 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
9 # * https://www.apache.org/licenses/LICENSE-2.0
1010 # *
1111 # * Unless required by applicable law or agreed to in writing,
1212 # * software distributed under the License is distributed on an
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
0 <?xml version="1.0"?>
1 <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" "http://www.puppycrawl.com/dtds/configuration_1_1.dtd">
2 <!--
3 Licensed to the Apache Software Foundation (ASF) under one
4 or more contributor license agreements. See the NOTICE file
5 distributed with this work for additional information
6 regarding copyright ownership. The ASF licenses this file
7 to you under the Apache License, Version 2.0 (the
8 "License"); you may not use this file except in compliance
9 with the License. You may obtain a copy of the License at
10
11 http://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing,
14 software distributed under the License is distributed on an
15 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, either express or implied. See the License for the
17 specific language governing permissions and limitations
18 under the License.
19 -->
20 <module name="Checker">
21
22 <!-- required license file -->
23 <module name="Header">
24 <property name="headerFile" value="${checkstyle.src.dir}/RequiredHeader.txt"/>
25 <property name="ignoreLines" value="2"/>
26 </module>
27
28 <!-- Items moved out of TreeWalker for new versions of Checkstyle -->
29 <module name="FileLength"/>
30 <module name="FileTabCharacter"/>
31
32 <module name="TreeWalker">
33 <!-- Javadoc requirements -->
34 <!-- TODO uncomment this when javadoc will be improved
35 <module name="JavadocType">
36 <property name="scope" value="protected"/>
37 </module>
38 <module name="JavadocMethod">
39 <property name="scope" value="protected"/>
40 <property name="allowUndeclaredRTE" value="true"/>
41 </module>
42 <module name="JavadocVariable">
43 <property name="scope" value="public"/>
44 </module>
45 -->
46
47 <!-- element naming -->
48 <module name="PackageName"/>
49 <module name="TypeName"/>
50 <module name="ConstantName"/>
51 <module name="LocalFinalVariableName"/>
52 <module name="LocalVariableName"/>
53 <module name="MemberName"/>
54 <module name="MethodName"/>
55 <module name="ParameterName"/>
56 <module name="StaticVariableName"/>
57
58 <!-- Import conventions -->
59 <module name="AvoidStarImport"/>
60 <!-- <module name="IllegalImport"/> -->
61 <module name="RedundantImport"/>
62 <module name="UnusedImports"/>
63
64 <!-- size limits -->
65 <module name="LineLength">
66 <property name="max" value="100"/>
67 <property name="ignorePattern" value="^ *\* *[^ ]+$"/>
68 <property name="tabWidth" value="4"/>
69 </module>
70 <module name="MethodLength"/>
71 <module name="ParameterNumber"/>
72
73 <!-- whitespace checks -->
74 <module name="EmptyForIteratorPad"/>
75 <module name="NoWhitespaceAfter"/>
76 <module name="NoWhitespaceBefore"/>
77 <module name="OperatorWrap"/>
78 <module name="ParenPad"/>
79 <module name="WhitespaceAfter"/>
80 <module name="WhitespaceAround"/>
81
82 <!-- Modifier Checks -->
83 <module name="ModifierOrder"/>
84
85
86 <!-- Checks for blocks -->
87 <module name="AvoidNestedBlocks"/>
88 <module name="EmptyBlock">
89 <property name="option" value="text"/>
90 </module>
91 <module name="LeftCurly"/>
92 <module name="NeedBraces"/>
93 <module name="RightCurly"/>
94
95
96 <!-- Checks for common coding problems -->
97 <!--<module name="AvoidInlineConditionals"/> -->
98 <!--<module name="DoubleCheckedLocking"/>--> <!-- removed in checkstyle 5.6 -->
99 <module name="EmptyStatement"/>
100 <module name="EqualsHashCode"/>
101 <module name="IllegalInstantiation">
102 <property name="classes" value="java.lang.Boolean"/>
103 </module>
104 <module name="InnerAssignment"/>
105 <module name="MagicNumber"/>
106 <module name="MissingSwitchDefault"/>
107 <module name="RedundantThrows">
108 <property name="allowUnchecked" value="true"/>
109 </module>
110 <module name="SimplifyBooleanExpression"/>
111 <module name="SimplifyBooleanReturn"/>
112
113 <!-- Checks for class design -->
114 <!-- <module name="DesignForExtension"/> -->
115 <module name="FinalClass"/>
116 <module name="HideUtilityClassConstructor"/>
117 <module name="InterfaceIsType"/>
118 <module name="VisibilityModifier"/>
119
120 <!-- Miscellaneous other checks. -->
121 <module name="ArrayTypeStyle"/>
122 <!--
123 <module name="GenericIllegalRegexp">
124 <property name="format" value="\s+$"/>
125 <property name="message" value="Line has trailing spaces."/>
126 </module>
127 -->
128 <!--
129 <module name="TodoComment"/>
130 -->
131 <module name="UpperEll"/>
132 <!-- allow comment suppression of checks -->
133 <module name="FileContentsHolder"/>
134 </module>
135
136 <!--TODO: comment this out, if Simian is not present -->
137 <!--
138 <module name="au.com.redhillconsulting.simian.SimianCheck"/>
139 -->
140
141 <module name="SuppressionCommentFilter">
142 <property name="offCommentFormat" value="CheckStyle\:([\w\|]+) *OFF"/>
143 <property name="onCommentFormat" value="CheckStyle\:([\w\|]+) *ON"/>
144 <property name="checkFormat" value="$1"/>
145 </module>
146
147 <module name="SuppressionFilter">
148 <property name="file" value="${basedir}/src/etc/checkstyle/checkstyle-suppress.xml"/>
149 </module>
150
151 </module>
0 <?xml version="1.0" encoding="UTF-8"?>
1 <!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
2 <!--
3 Licensed to the Apache Software Foundation (ASF) under one
4 or more contributor license agreements. See the NOTICE file
5 distributed with this work for additional information
6 regarding copyright ownership. The ASF licenses this file
7 to you under the Apache License, Version 2.0 (the
8 "License"); you may not use this file except in compliance
9 with the License. You may obtain a copy of the License at
10
11 https://www.apache.org/licenses/LICENSE-2.0
12
13 Unless required by applicable law or agreed to in writing,
14 software distributed under the License is distributed on an
15 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 KIND, either express or implied. See the License for the
17 specific language governing permissions and limitations
18 under the License.
19 -->
20 <module name="Checker">
21 <!-- required licence file -->
22 <module name="Header">
23 <property name="headerFile" value="${checkstyle.src.dir}/RequiredHeader.txt"/>
24 <property name="ignoreLines" value="2"/>
25 </module>
26
27 <!-- Items moved out of TreeWalker for new versions of Checkstyle -->
28 <module name="FileLength"/>
29 <module name="FileTabCharacter"/>
30
31 <module name="TreeWalker">
32 <!-- Javadoc requirements -->
33 <module name="JavadocType">
34 <property name="scope" value="protected"/>
35 </module>
36 <module name="JavadocMethod">
37 <property name="scope" value="protected"/>
38 <property name="allowUndeclaredRTE" value="true"/>
39 </module>
40 <module name="JavadocVariable">
41 <property name="scope" value="public"/>
42 </module>
43
44 <!-- element naming -->
45 <module name="PackageName"/>
46 <module name="TypeName"/>
47 <module name="ConstantName"/>
48 <module name="LocalFinalVariableName"/>
49 <module name="LocalVariableName"/>
50 <module name="MemberName"/>
51 <module name="MethodName"/>
52 <module name="ParameterName"/>
53 <module name="StaticVariableName"/>
54
55 <!-- Import conventions -->
56 <module name="AvoidStarImport"/>
57 <module name="IllegalImport"/>
58 <module name="RedundantImport"/>
59 <module name="UnusedImports"/>
60
61 <!-- size limits -->
62 <module name="LineLength">
63 <property name="max" value="100"/>
64 <property name="ignorePattern" value="^ *\* *[^ ]+$"/>
65 <property name="tabWidth" value="4"/>
66 </module>
67 <module name="MethodLength"/>
68 <module name="ParameterNumber"/>
69
70 <!-- whitespace checks -->
71 <module name="EmptyForIteratorPad"/>
72 <module name="NoWhitespaceAfter"/>
73 <module name="NoWhitespaceBefore"/>
74 <module name="OperatorWrap"/>
75 <module name="ParenPad"/>
76 <module name="WhitespaceAfter"/>
77 <module name="WhitespaceAround"/>
78
79 <!-- Modifier Checks -->
80 <module name="ModifierOrder"/>
81 <module name="RedundantModifier"/>
82
83 <!-- Checks for blocks -->
84 <module name="AvoidNestedBlocks"/>
85 <module name="EmptyBlock">
86 <property name="option" value="text"/>
87 </module>
88 <module name="LeftCurly"/>
89 <module name="NeedBraces"/>
90 <module name="RightCurly"/>
91
92 <!-- Checks for common coding problems -->
93 <!-- <module name="AvoidInlineConditionals"/> -->
94 <!-- <module name="DoubleCheckedLocking"/> --> <!-- removed in checkstyle 5.6 -->
95 <module name="EmptyStatement"/>
96 <module name="EqualsHashCode"/>
97 <module name="IllegalInstantiation">
98 <property name="classes" value="java.lang.Boolean"/>
99 </module>
100 <module name="InnerAssignment"/>
101 <module name="MagicNumber"/>
102 <module name="MissingSwitchDefault"/>
103 <!-- Allow redundant throw declarations for doc purposes
104 <module name="RedundantThrows">
105 <property name="allowUnchecked" value="true"/>
106 </module>
107 -->
108 <module name="SimplifyBooleanExpression"/>
109 <module name="SimplifyBooleanReturn"/>
110
111 <!-- Checks for class design -->
112 <!-- <module name="DesignForExtension"/> -->
113 <module name="FinalClass"/>
114 <module name="HideUtilityClassConstructor"/>
115 <module name="InterfaceIsType"/>
116 <module name="VisibilityModifier"/>
117
118 <!-- Miscellaneous other checks. -->
119 <module name="ArrayTypeStyle"/>
120 <!-- <module name="TodoComment"/> -->
121 <module name="UpperEll"/>
122 <!-- allow comment suppression of checks -->
123 <module name="FileContentsHolder"/>
124 <!--
125 <module name="GenericIllegalRegexp">
126 <property name="format" value="\s+$"/>
127 <property name="message" value="Line has trailing spaces."/>
128 </module>
129 -->
130 </module>
131
132 <module name="RegexpSingleline">
133 <!-- \s matches whitespace character, $ matches end of line. -->
134 <property name="format" value="\s+$"/>
135 </module>
136
137 <!-- <module name="au.com.redhillconsulting.simian.SimianCheck"/> -->
138 <module name="SuppressionCommentFilter">
139 <property name="offCommentFormat" value="CheckStyle\:([\w\|]+) *OFF"/>
140 <property name="onCommentFormat" value="CheckStyle\:([\w\|]+) *ON"/>
141 <property name="checkFormat" value="$1"/>
142 </module>
143
144 <module name="SuppressionFilter">
145 <property name="file" value="${checkstyle.src.dir}/checkstyle-suppress.xml"/>
146 </module>
147
148 </module>
00 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
11 xmlns:lxslt="http://xml.apache.org/xslt"
2 xmlns:redirect="org.apache.xalan.lib.Redirect"
2 xmlns:redirect="http://xml.apache.org/xalan/redirect"
33 extension-element-prefixes="redirect">
44
55 <!--
1010 (the "License"); you may not use this file except in compliance with
1111 the License. You may obtain a copy of the License at
1212
13 http://www.apache.org/licenses/LICENSE-2.0
13 https://www.apache.org/licenses/LICENSE-2.0
1414
1515 Unless required by applicable law or agreed to in writing, software
1616 distributed under the License is distributed on an "AS IS" BASIS,
7777 <tr>
7878 <td class="text-align:right">Designed for use with
7979 <a href='http://checkstyle.sourceforge.net/'>CheckStyle</a> and
80 <a href='http://ant.apache.org/'>Ant</a>.</td>
80 <a href='https://ant.apache.org/'>Ant</a>.</td>
8181 </tr>
8282 </table>
8383 <hr size="1"/>
1010 "License"); you may not use this file except in compliance
1111 with the License. You may obtain a copy of the License at
1212
13 http://www.apache.org/licenses/LICENSE-2.0
13 https://www.apache.org/licenses/LICENSE-2.0
1414
1515 Unless required by applicable law or agreed to in writing,
1616 software distributed under the License is distributed on an
1717 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1818 KIND, either express or implied. See the License for the
1919 specific language governing permissions and limitations
20 under the License.
20 under the License.
2121 -->
2222 <suppressions>
23 <suppress checks="MagicNumber" files=".*[\\/]test[\\/]java[\\/].*"/>
24 </suppressions>
23 <suppress checks="MagicNumber" files=".*[\\/]test[\\/]java[\\/].*"/>
24 </suppressions>
77 (the "License"); you may not use this file except in compliance with
88 the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing, software
1313 distributed under the License is distributed on an "AS IS" BASIS,
2929 <xsl:value-of select="@message"/>
3030 </xsl:template>
3131 </xsl:stylesheet>
32
1010 (the "License"); you may not use this file except in compliance with
1111 the License. You may obtain a copy of the License at
1212
13 http://www.apache.org/licenses/LICENSE-2.0
13 https://www.apache.org/licenses/LICENSE-2.0
1414
1515 Unless required by applicable law or agreed to in writing, software
1616 distributed under the License is distributed on an "AS IS" BASIS,
125125 </xsl:attribute>
126126 </xsl:template>
127127 </xsl:stylesheet>
128
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
3131 <name>Apache Ivy</name>
3232 <url>${ivy.pom.url}</url>
3333 <scm>
34 <connection>scm:svn:http://svn.apache.org/repos/asf/ant/ivy/core/trunk/</connection>
34 <connection>scm:svn:https://svn.apache.org/repos/asf/ant/ivy/core/trunk/</connection>
3535 <developerConnection>scm:svn:https://svn.apache.org/repos/asf/ant/ivy/core/trunk</developerConnection>
36 <url>http://svn.apache.org/repos/asf/ant/ivy/core/trunk</url>
36 <url>https://svn.apache.org/repos/asf/ant/ivy/core/trunk</url>
3737 </scm>
3838 <mailingLists>
3939 <mailingList>
4141 <subscribe>dev-subscribe@ant.apache.org</subscribe>
4242 <unsubscribe>dev-unsubscribe@ant.apache.org</unsubscribe>
4343 <post>dev@ant.apache.org</post>
44 <archive>http://mail-archives.apache.org/mod_mbox/ant-dev</archive>
44 <archive>https://mail-archives.apache.org/mod_mbox/ant-dev</archive>
4545 </mailingList>
4646 <mailingList>
4747 <name>Ivy Users List</name>
4848 <subscribe>ivy-user-subscribe@ant.apache.org</subscribe>
4949 <unsubscribe>ivy-user-unsubscribe@ant.apache.org</unsubscribe>
5050 <post>ivy-user@ant.apache.org</post>
51 <archive>http://mail-archives.apache.org/mod_mbox/ant-ivy-user</archive>
51 <archive>https://mail-archives.apache.org/mod_mbox/ant-ivy-user</archive>
5252 </mailingList>
5353 </mailingLists>
5454 <issueManagement>
5555 <system>jira</system>
56 <url>http://issues.apache.org/jira/browse/IVY</url>
56 <url>https://issues.apache.org/jira/browse/IVY</url>
5757 </issueManagement>
5858 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1717 -->
1818 <project xmlns:ivy="antlib:org.apache.ivy.ant" name="ivy-bintray-example" default="retrieve">
1919 <target name="retrieve">
20 <ivy:retrieve />
20 <ivy:retrieve/>
21 </target>
22
23 <target name="clean">
24 <echo>Nothing to clean here.</echo>
2125 </target>
2226 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1919 <info organisation="org.apache" module="hello-ivy"/>
2020 <dependencies>
2121 <!-- https://jcenter.bintray.com/ -->
22 <dependency org="org.jfrog.artifactory.client" name="artifactory-cli" rev="1.0" />
23 <dependency org="org.jfrog.artifactory.client" name="artifactory-cli" rev="1.0" />
24 <dependency org="org.jfrog" name="build-info-api" rev="1.3.1" />
22 <dependency org="org.jfrog.artifactory.client" name="artifactory-cli" rev="1.0"/>
23 <dependency org="org.jfrog.artifactory.client" name="artifactory-cli" rev="1.0"/>
24 <dependency org="org.jfrog" name="build-info-api" rev="1.3.1"/>
2525 <!-- https://dl.bintray.com/dsowerby/maven/ -->
26 <dependency org="uk.q3c.krail" name="krail" rev="0.7.0" />
26 <dependency org="uk.q3c.krail" name="krail" rev="0.7.0"/>
2727 <!-- https://dl.bintray.com/igelgrun/batrak/ -->
28 <dependency org="igel.batrak" name="batrak-core" rev="0.1" />
28 <dependency org="igel.batrak" name="batrak-core" rev="0.1"/>
2929 </dependencies>
3030 </ivy-module>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
19 <!-- ======================================================================
19 <!-- ======================================================================
2020 This is a sample project to build our own ivy repository.
2121 ====================================================================== -->
2222 <project name="ivy-repository" default="maven2" xmlns:ivy="antlib:org.apache.ivy.ant">
23 <property name="settings.dir" value="settings"/>
24 <property name="from.resolver" value="libraries"/>
25 <property name="to.resolver" value="my-repository"/>
26
27 <property name="ivy.cache.dir" value="${basedir}/cache" />
28 <property name="dest.repo.dir" value="${basedir}/myrepository" />
23 <property name="settings.dir" value="settings"/>
24 <property name="from.resolver" value="libraries"/>
25 <property name="to.resolver" value="my-repository"/>
2926
30 <property name="ivy.jar.dir" value="${user.home}/.ivy2/jars" />
31 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
27 <property name="ivy.cache.dir" value="${basedir}/cache"/>
28 <property name="dest.repo.dir" value="${basedir}/myrepository"/>
3229
33 <!-- =================================
34 target: load-ivy
35 this target is not necessary if you put ivy.jar in your ant lib directory
36 if you already have ivy 1.4 in your ant lib, you can simply remove this
37 target
30 <property name="ivy.jar.dir" value="${user.home}/.ivy2/jars"/>
31 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
32
33 <!-- =================================
34 target: load-ivy
35 this target is not necessary if you put ivy.jar in your ant lib directory
36 if you already have ivy 1.4 in your ant lib, you can simply remove this
37 target
3838 ================================= -->
3939 <target name="load-ivy">
40 <!-- try to load ivy here from home ivy dir, in case the user has not already dropped
41 it into ant's lib dir (note that the latter copy will always take precedence).
42 We will not fail as long as ivy home lib dir exists (it may be empty) and
43 ivy is in at least one of ant's lib dir or the ivy home lib dir. -->
44 <path id="ivy.lib.path">
45 <pathelement location="${ivy.jar.file}"/>
46 </path>
47 <taskdef resource="org/apache/ivy/ant/antlib.xml"
48 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
49 </target>
40 <!-- try to load ivy here from home ivy dir, in case the user has not already dropped
41 it into ant's lib dir (note that the latter copy will always take precedence).
42 We will not fail as long as ivy home lib dir exists (it may be empty) and
43 ivy is in at least one of ant's lib dir or the ivy home lib dir. -->
44 <path id="ivy.lib.path">
45 <pathelement location="${ivy.jar.file}"/>
46 </path>
47 <taskdef resource="org/apache/ivy/ant/antlib.xml"
48 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
49 </target>
5050
51 <!-- - - - - - - - - - - - - - - - - -
52 target: init-ivy
51 <!-- - - - - - - - - - - - - - - - - -
52 target: init-ivy
5353 - - - - - - - - - - - - - - - - - -->
5454 <target name="init-ivy" depends="load-ivy">
55 <ivy:settings id="basic.settings" file="${settings.dir}/ivysettings-basic.xml"/>
56 <ivy:settings id="advanced.settings" file="${settings.dir}/ivysettings-advanced.xml"/>
55 <ivy:settings id="basic.settings" file="${settings.dir}/ivysettings-basic.xml"/>
56 <ivy:settings id="advanced.settings" file="${settings.dir}/ivysettings-advanced.xml"/>
5757 </target>
5858
59
60 <!-- =================================
59
60 <!-- =================================
6161 target: maven2
6262 maven 2 no namespace and no dependencies
6363 ================================= -->
6464 <target name="maven2" depends="init-ivy"
65 description="--> install module from maven 2 repository">
66 <ivy:install settingsRef="basic.settings"
67 organisation="commons-lang" module="commons-lang" revision="1.0"
68 from="${from.resolver}" to="${to.resolver}" />
65 description="--> install module from maven 2 repository">
66 <ivy:install settingsRef="basic.settings"
67 organisation="commons-lang" module="commons-lang" revision="1.0"
68 from="${from.resolver}" to="${to.resolver}"/>
6969 </target>
7070
71 <!-- =================================
71 <!-- =================================
7272 target: maven2-deps
7373 maven 2 no namespace with dependencies
7474 ================================= -->
75 <target name="maven2-deps" depends="init-ivy"
76 description="--> install module from maven 2 repository with dependencies">
77 <ivy:install settingsRef="basic.settings"
78 organisation="org.hibernate" module="hibernate" revision="3.2.5.ga"
79 from="${from.resolver}" to="${to.resolver}" transitive="true" />
75 <target name="maven2-deps" depends="init-ivy"
76 description="--> install module from maven 2 repository with dependencies">
77 <ivy:install settingsRef="basic.settings"
78 organisation="org.hibernate" module="hibernate" revision="3.2.5.ga"
79 from="${from.resolver}" to="${to.resolver}" transitive="true"/>
8080 </target>
8181
82 <!-- =================================
82 <!-- =================================
8383 target: maven2-namespace
8484 maven 2 with namespace no dependencies
8585 ================================= -->
86 <target name="maven2-namespace" depends="init-ivy"
87 description="--> install module from maven 2 using namespaces">
88 <ivy:install settingsRef="advanced.settings"
89 organisation="apache" module="commons-lang" revision="1.0"
90 from="${from.resolver}" to="${to.resolver}" />
86 <target name="maven2-namespace" depends="init-ivy"
87 description="--> install module from maven 2 using namespaces">
88 <ivy:install settingsRef="advanced.settings"
89 organisation="apache" module="commons-lang" revision="1.0"
90 from="${from.resolver}" to="${to.resolver}"/>
9191 </target>
9292
93 <!-- =================================
93 <!-- =================================
9494 target: maven2-namespace-deps
9595 maven 2 with namespace and dependencies
9696 ================================= -->
9797 <target name="maven2-namespace-deps" depends="init-ivy"
98 description="--> install module with dependencies from maven2 repo using namespaces">
99 <ivy:install settingsRef="advanced.settings"
100 organisation="hibernate" module="hibernate" revision="3.2.5.ga"
101 from="${from.resolver}" to="${to.resolver}" transitive="true" />
98 description="--> install module with dependencies from maven2 repo using namespaces">
99 <ivy:install settingsRef="advanced.settings"
100 organisation="hibernate" module="hibernate" revision="3.2.5.ga"
101 from="${from.resolver}" to="${to.resolver}" transitive="true"/>
102102 </target>
103103
104 <!-- =================================
104 <!-- =================================
105105 target: clean-cache
106106 ================================= -->
107107 <target name="clean-cache" depends="init-ivy" description="--> clean the cache">
108 <ivy:cleancache settingsRef="basic.settings" />
109 <ivy:cleancache settingsRef="advanced.settings" />
110 <delete dir="${ivy.cache.dir}" failonerror="true" />
108 <ivy:cleancache settingsRef="basic.settings"/>
109 <ivy:cleancache settingsRef="advanced.settings"/>
110 <delete dir="${ivy.cache.dir}" failonerror="true"/>
111111 </target>
112112
113 <!-- =================================
113 <!-- =================================
114114 target: clean-repo
115115 ================================= -->
116116 <target name="clean-repo" description="--> clean the destination repository">
117 <delete dir="${dest.repo.dir}" failonerror="true" />
117 <delete dir="${dest.repo.dir}" failonerror="true"/>
118118 </target>
119
120 <target name="clean" depends="clean-repo"/>
119121 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <settings defaultResolver="my-repository"
20 defaultConflictManager="all" /> <!-- in order to get all revisions without any eviction -->
21 <caches defaultCacheDir="${ivy.cache.dir}/advanced" />
19 <settings defaultResolver="my-repository"
20 defaultConflictManager="all"/> <!-- in order to get all revisions without any eviction -->
21 <caches defaultCacheDir="${ivy.cache.dir}/advanced"/>
2222
23 <!--
24 You can override this property to use one of the mirrors listed on
25 http://docs.codehaus.org/display/MAVENUSER/Mirrors+Repositories
26 -->
27 <property name="ibiblio-maven2-root" value="https://repo1.maven.org/maven2/" override="false" />
23 <!--
24 You can override this property to use one of the mirrors listed on
25 http://docs.codehaus.org/display/MAVENUSER/Mirrors+Repositories
26 -->
27 <property name="ibiblio-maven2-root" value="https://repo1.maven.org/maven2/" override="false"/>
2828
29 <namespaces>
30 <namespace name="maven2">
31 <rule> <!-- imported apache maven1 projects -->
32 <fromsystem>
33 <src org="apache" module=".+"/>
34
29 <namespaces>
30 <namespace name="maven2">
31 <rule> <!-- imported apache maven1 projects -->
32 <fromsystem>
33 <src org="apache" module=".+"/>
3534 <dest org="$m0" module="$m0"/>
3635 </fromsystem>
3736 <tosystem>
38 <src org="commons-.+" module="commons-.+" />
39 <src org="ant" module=".*" />
40 <src org="avalon-.+" module="avalon-.+" />
41 <src org="avalon" module="avalon" />
42 <src org="axis" module="axis" />
43 <src org="axis2" module="axis2" />
44 <src org="batik" module="batik" />
45 <src org="bcel" module="bcel" />
46 <src org="beehive" module="beehive" />
47 <src org="bsf" module="bsf" />
48 <src org="cactus" module="cactus" />
49 <src org="cocoon" module="cocoon" />
50 <src org="cornerstone-.+" module="cornerstone-.+" />
51 <src org="create-checksums" module="create-checksums" />
52 <src org="crimson" module="crimson" />
53 <src org="directory-.+" module="directory-.+" />
54 <src org="directory" module="directory" />
55 <src org="ecs" module="ecs" />
56 <src org="excalibur-.+" module="excalibur-.+" />
57 <src org="excalibur" module="excalibur" />
58 <src org="fop" module="fop" />
59 <src org="fulcrum" module="fulcrum" />
60 <src org="geronimo-.+" module="geronimo-.+" />
61 <src org="geronimo" module="geronimo" />
62 <src org="hivemind" module="hivemind" />
63 <src org="jakarta-regexp" module="jakarta-regexp" />
64 <src org="james" module="james" />
65 <src org="jaxme" module="jaxme" />
66 <src org="jcs-javagroups" module="jcs-javagroups" />
67 <src org="jcs" module="jcs" />
68 <src org="jspapi" module="jspapi" />
69 <src org="jstl" module="jstl" />
70 <src org="juddi" module="juddi" />
71 <src org="log4j" module="log4j" />
72 <src org="logkit" module="logkit" />
73 <src org="lucene" module="lucene" />
74 <src org="magicGball" module="magicGball" />
75 <src org="maven" module="maven" />
76 <src org="merlin-developer" module="merlin-developer" />
77 <src org="merlin" module="merlin" />
78 <src org="muse" module="muse" />
79 <src org="myfaces" module="myfaces" />
80 <src org="nekohtml" module="nekohtml" />
81 <src org="ojb" module="ojb" />
82 <src org="oro" module="oro" />
83 <src org="pluto-container" module="pluto-container" />
84 <src org="poi" module="poi" />
85 <src org="pubscribe" module="pubscribe" />
86 <src org="sandesha" module="sandesha" />
87 <src org="servletapi" module="servletapi" />
88 <src org="slide" module=".*" />
89 <src org="stratum" module="stratum" />
90 <src org="struts" module="struts" />
91 <src org="taglibs" module="taglibs" />
92 <src org="tapestry" module="tapestry" />
93 <src org="tomcat-util" module="tomcat-util" />
94 <src org="tomcat" module="tomcat" />
95 <src org="torque" module="torque" />
96 <src org="turbine" module="turbine" />
97 <src org="velocity-.+" module="velocity-.+" />
98 <src org="velocity" module="velocity" />
99 <src org="ws-commons.*" module="ws-commons.*" />
100 <src org="wsdl4j" module="wsdl4j" />
101 <src org="wsrf" module="wsrf" />
102 <src org="xalan" module="xalan" />
103 <src org="xerces" module=".*" />
104 <src org="xercesjarv" module="xercesjarv" />
105 <src org="xml-apis" module="xml-apis" />
106 <src org="xml-resolver" module="xml-resolver" />
107 <src org="xml-security" module="xml-security" />
108 <src org="xmlbeans" module="xmlbeans" />
109 <src org="xmlrpc" module="xmlrpc" />
110
111 <dest org="apache" module="$m0"/>
112 </tosystem>
113 </rule>
37 <src org="commons-.+" module="commons-.+"/>
38 <src org="ant" module=".*"/>
39 <src org="avalon-.+" module="avalon-.+"/>
40 <src org="avalon" module="avalon"/>
41 <src org="axis" module="axis"/>
42 <src org="axis2" module="axis2"/>
43 <src org="batik" module="batik"/>
44 <src org="bcel" module="bcel"/>
45 <src org="beehive" module="beehive"/>
46 <src org="bsf" module="bsf"/>
47 <src org="cactus" module="cactus"/>
48 <src org="cocoon" module="cocoon"/>
49 <src org="cornerstone-.+" module="cornerstone-.+"/>
50 <src org="create-checksums" module="create-checksums"/>
51 <src org="crimson" module="crimson"/>
52 <src org="directory-.+" module="directory-.+"/>
53 <src org="directory" module="directory"/>
54 <src org="ecs" module="ecs"/>
55 <src org="excalibur-.+" module="excalibur-.+"/>
56 <src org="excalibur" module="excalibur"/>
57 <src org="fop" module="fop"/>
58 <src org="fulcrum" module="fulcrum"/>
59 <src org="geronimo-.+" module="geronimo-.+"/>
60 <src org="geronimo" module="geronimo"/>
61 <src org="hivemind" module="hivemind"/>
62 <src org="jakarta-regexp" module="jakarta-regexp"/>
63 <src org="james" module="james"/>
64 <src org="jaxme" module="jaxme"/>
65 <src org="jcs-javagroups" module="jcs-javagroups"/>
66 <src org="jcs" module="jcs"/>
67 <src org="jspapi" module="jspapi"/>
68 <src org="jstl" module="jstl"/>
69 <src org="juddi" module="juddi"/>
70 <src org="log4j" module="log4j"/>
71 <src org="logkit" module="logkit"/>
72 <src org="lucene" module="lucene"/>
73 <src org="magicGball" module="magicGball"/>
74 <src org="maven" module="maven"/>
75 <src org="merlin-developer" module="merlin-developer"/>
76 <src org="merlin" module="merlin"/>
77 <src org="muse" module="muse"/>
78 <src org="myfaces" module="myfaces"/>
79 <src org="nekohtml" module="nekohtml"/>
80 <src org="ojb" module="ojb"/>
81 <src org="oro" module="oro"/>
82 <src org="pluto-container" module="pluto-container"/>
83 <src org="poi" module="poi"/>
84 <src org="pubscribe" module="pubscribe"/>
85 <src org="sandesha" module="sandesha"/>
86 <src org="servletapi" module="servletapi"/>
87 <src org="slide" module=".*"/>
88 <src org="stratum" module="stratum"/>
89 <src org="struts" module="struts"/>
90 <src org="taglibs" module="taglibs"/>
91 <src org="tapestry" module="tapestry"/>
92 <src org="tomcat-util" module="tomcat-util"/>
93 <src org="tomcat" module="tomcat"/>
94 <src org="torque" module="torque"/>
95 <src org="turbine" module="turbine"/>
96 <src org="velocity-.+" module="velocity-.+"/>
97 <src org="velocity" module="velocity"/>
98 <src org="ws-commons.*" module="ws-commons.*"/>
99 <src org="wsdl4j" module="wsdl4j"/>
100 <src org="wsrf" module="wsrf"/>
101 <src org="xalan" module="xalan"/>
102 <src org="xerces" module=".*"/>
103 <src org="xercesjarv" module="xercesjarv"/>
104 <src org="xml-apis" module="xml-apis"/>
105 <src org="xml-resolver" module="xml-resolver"/>
106 <src org="xml-security" module="xml-security"/>
107 <src org="xmlbeans" module="xmlbeans"/>
108 <src org="xmlrpc" module="xmlrpc"/>
114109
115 <rule> <!-- new apache projects -->
116 <fromsystem>
117 <src org="apache" />
118 <dest org="org.apache"/>
119 </fromsystem>
120 <tosystem>
121 <src org="org.apache" />
122 <dest org="apache" />
123 </tosystem>
124 </rule>
125 <rule> <!-- hibernate -->
126 <fromsystem>
127 <src org="hibernate" />
128 <dest org="org.hibernate"/>
129 </fromsystem>
130 <tosystem>
131 <src org="org.hibernate" />
132 <dest org="hibernate" />
133 </tosystem>
134 </rule>
135 <rule> <!-- net.sf projects -->
136 <fromsystem>
137 <src org="ehcache" />
138 <dest org="net.sf.$o0"/>
139 </fromsystem>
140 <tosystem>
141 <src org="net.sf.(.+)" />
142 <dest org="$o1" />
143 </tosystem>
144 </rule>
145 </namespace>
146 </namespaces>
110 <dest org="apache" module="$m0"/>
111 </tosystem>
112 </rule>
147113
148 <resolvers>
149 <filesystem name="my-repository">
150 <ivy pattern="${dest.repo.dir}/advanced/[organisation]/[module]/ivys/ivy-[revision].xml"/>
151 <artifact pattern="${dest.repo.dir}/advanced/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
152 </filesystem>
153
154 <ibiblio name="libraries"
155 root="${ibiblio-maven2-root}"
156 m2compatible="true"
157 namespace="maven2"
158 />
159 </resolvers>
114 <rule> <!-- new apache projects -->
115 <fromsystem>
116 <src org="apache"/>
117 <dest org="org.apache"/>
118 </fromsystem>
119 <tosystem>
120 <src org="org.apache"/>
121 <dest org="apache"/>
122 </tosystem>
123 </rule>
124 <rule> <!-- hibernate -->
125 <fromsystem>
126 <src org="hibernate"/>
127 <dest org="org.hibernate"/>
128 </fromsystem>
129 <tosystem>
130 <src org="org.hibernate"/>
131 <dest org="hibernate"/>
132 </tosystem>
133 </rule>
134 <rule> <!-- net.sf projects -->
135 <fromsystem>
136 <src org="ehcache"/>
137 <dest org="net.sf.$o0"/>
138 </fromsystem>
139 <tosystem>
140 <src org="net.sf.(.+)"/>
141 <dest org="$o1"/>
142 </tosystem>
143 </rule>
144 </namespace>
145 </namespaces>
146
147 <resolvers>
148 <filesystem name="my-repository">
149 <ivy pattern="${dest.repo.dir}/advanced/[organisation]/[module]/ivys/ivy-[revision].xml"/>
150 <artifact pattern="${dest.repo.dir}/advanced/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
151 </filesystem>
152
153 <ibiblio name="libraries"
154 root="${ibiblio-maven2-root}"
155 m2compatible="true"
156 namespace="maven2"/>
157 </resolvers>
160158 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <settings defaultResolver="libraries"
20 defaultConflictManager="all" /> <!-- in order to get all revisions without any eviction -->
21 <caches defaultCacheDir="${ivy.cache.dir}/no-namespace" />
22 <resolvers>
23 <ibiblio name="libraries" m2compatible="true" />
24 <filesystem name="my-repository">
25 <ivy pattern="${dest.repo.dir}/no-namespace/[organisation]/[module]/ivys/ivy-[revision].xml"/>
26 <artifact pattern="${dest.repo.dir}/no-namespace/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
27 </filesystem>
28 </resolvers>
19 <settings defaultResolver="libraries"
20 defaultConflictManager="all"/> <!-- in order to get all revisions without any eviction -->
21 <caches defaultCacheDir="${ivy.cache.dir}/no-namespace"/>
22 <resolvers>
23 <ibiblio name="libraries" m2compatible="true"/>
24 <filesystem name="my-repository">
25 <ivy pattern="${dest.repo.dir}/no-namespace/[organisation]/[module]/ivys/ivy-[revision].xml"/>
26 <artifact pattern="${dest.repo.dir}/no-namespace/[organisation]/[module]/[type]s/[artifact]-[revision].[ext]"/>
27 </filesystem>
28 </resolvers>
2929 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project default="clean-all" xmlns:ivy="antlib:org.apache.ivy.ant">
19
20 <!-- =================================
21 target: clean
19
20 <!-- =================================
21 target: clean
2222 ================================= -->
2323 <target name="clean" description="--> clean directories">
24 <ant dir="chainedresolvers-project" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false" />
24 <ant dir="chainedresolvers-project" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false"/>
2525 </target>
26
27 <!-- =================================
28 target: clean-cache
26
27 <!-- =================================
28 target: clean-cache
2929 ================================= -->
30 <target name="clean-cache" description="--> clean the ivy cache">
31 <property name="ivy.settings.dir" value="settings" />
32 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
33 <ivy:cleancache />
34 </target>
35
36 <target name="clean-all" depends="clean, clean-cache" description="--> clean directories and ivy cache"/>
30 <target name="clean-cache" description="--> clean the ivy cache">
31 <property name="ivy.settings.dir" value="settings"/>
32 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml"/>
33 <ivy:cleancache/>
34 </target>
35
36 <target name="clean-all" depends="clean,clean-cache" description="--> clean directories and ivy cache"/>
3737 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="chainedresolvers-project" default="run" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="${basedir}/lib" />
21 <property name="build.dir" value="${basedir}/build" />
22 <property name="src.dir" value="${basedir}/src" />
23
20 <property name="lib.dir" value="${basedir}/lib"/>
21 <property name="build.dir" value="${basedir}/build"/>
22 <property name="src.dir" value="${basedir}/src"/>
23
2424 <!-- ivy properties used -->
25 <property name="ivy.settings.dir" value="../settings" />
25 <property name="ivy.settings.dir" value="../settings"/>
2626
27 <!-- paths used for compilation and run -->
27 <!-- paths used for compilation and run -->
2828 <path id="lib.path.id">
29 <fileset dir="${lib.dir}" />
30 </path>
29 <fileset dir="${lib.dir}"/>
30 </path>
3131 <path id="run.path.id">
32 <path refid="lib.path.id" />
33 <path location="${build.dir}" />
32 <path refid="lib.path.id"/>
33 <path location="${build.dir}"/>
3434 </path>
35
36 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
37
38 <!-- =================================
39 target: resolve
35
36 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml"/>
37
38 <!-- =================================
39 target: resolve
4040 ================================= -->
4141 <target name="resolve" description="--> resolve and retrieve dependencies with ivy">
4242 <ivy:retrieve/>
4343 </target>
44
45 <!-- =================================
46 target: report
44
45 <!-- =================================
46 target: report
4747 ================================= -->
4848 <target name="report" depends="resolve" description="--> generates a report of dependencies">
4949 <ivy:report todir="${build.dir}"/>
5050 </target>
51
52 <!-- =================================
51
52 <!-- =================================
5353 target: run
5454 ================================= -->
5555 <target name="run" depends="resolve" description="--> compile and run the project">
56 <mkdir dir="${build.dir}" />
57 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id" />
56 <mkdir dir="${build.dir}"/>
57 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id"/>
5858 <java classpathref="run.path.id" classname="example.Hello"/>
5959 </target>
60
61 <!-- =================================
62 target: clean
60
61 <!-- =================================
62 target: clean
6363 ================================= -->
6464 <target name="clean" description="--> clean the project">
6565 <delete includeemptydirs="true">
6666 <fileset dir="${basedir}">
67 <exclude name="src/**" />
68 <exclude name="build.xml" />
69 <exclude name="ivy.xml" />
70 </fileset>
71 </delete>
67 <exclude name="src/**"/>
68 <exclude name="build.xml"/>
69 <exclude name="ivy.xml"/>
70 </fileset>
71 </delete>
7272 </target>
73
74 <!-- =================================
75 target: clean-cache
73
74 <!-- =================================
75 target: clean-cache
7676 ================================= -->
77 <target name="clean-cache" description="--> clean the ivy cache">
78 <ivy:cleancache />
79 </target>
77 <target name="clean-cache" description="--> clean the ivy cache">
78 <ivy:cleancache/>
79 </target>
8080 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
1919 <info organisation="org.apache" module="chained-resolvers"/>
2020 <dependencies>
21 <dependency org="commons-lang" name="commons-lang" rev="2.0" conf="default"/>
21 <dependency org="commons-lang" name="commons-lang" rev="2.6" conf="default"/>
2222 <dependency name="test" rev="1.0"/>
2323 </dependencies>
2424 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.commons.lang.WordUtils;
2020
2121 /**
22 * Simple example world to show how easy it is to retreive libs with ivy !!!
22 * Simple example world to show how easy it is to retreive libs with ivy !!!
2323 */
2424 public final class Hello {
2525 public static void main(String[] args) {
2626 String message = "example world !";
2727 System.out.println("standard message :" + message);
28 System.out.println("capitalized by " + WordUtils.class.getName()
28 System.out.println("capitalized by " + WordUtils.class.getName()
2929 + " : " + WordUtils.capitalizeFully(message));
30 System.out.println("upperCased by " + test.StringUtils.class.getName()
30 System.out.println("upperCased by " + test.StringUtils.class.getName()
3131 + " : " + test.StringUtils.upperCase(message));
3232 }
33
33
3434 private Hello() {
3535 }
3636 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
1919 <settings defaultResolver="chain-example"/>
2020 <resolvers>
2121 <chain name="chain-example">
2222 <filesystem name="libraries">
23 <artifact pattern="${ivy.settings.dir}/repository/[artifact]-[revision].[ext]" />
23 <artifact pattern="${ivy.settings.dir}/repository/[artifact]-[revision].[ext]"/>
2424 </filesystem>
25 <ibiblio name="ibiblio" m2compatible="true" />
25 <ibiblio name="ibiblio" m2compatible="true"/>
2626 </chain>
2727 </resolvers>
2828 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="configurations" default="run.dev" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="lib" />
21 <property name="build.dir" value="build" />
22 <property name="src.dir" value="src" />
23
20 <property name="lib.dir" value="lib"/>
21 <property name="build.dir" value="build"/>
22 <property name="src.dir" value="src"/>
23
2424 <!-- paths used for compilation and run -->
2525 <path id="compile.path.id">
26 <fileset dir="${lib.dir}/compile" />
27 </path>
26 <fileset dir="${lib.dir}/compile"/>
27 </path>
2828 <path id="lib.run.dev.id">
29 <path location="${build.dir}" />
30 <fileset dir="${lib.dir}/rundev" />
31 </path>
32 <path id="lib.run.prod.id">
33 <path location="${build.dir}" />
34 <fileset dir="${lib.dir}/runprod" />
29 <path location="${build.dir}"/>
30 <fileset dir="${lib.dir}/rundev"/>
3531 </path>
36
37 <!-- =================================
38 target: resolve
32 <path id="lib.run.prod.id">
33 <path location="${build.dir}"/>
34 <fileset dir="${lib.dir}/runprod"/>
35 </path>
36
37 <!-- =================================
38 target: resolve
3939 ================================= -->
4040 <target name="resolve" description="--> retreive dependencies with ivy">
41 <!-- conf="*" will copie artifacts defined for each conf in a dir matching conf name -->
42 <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact]-[revision].[ext]"/>
43 </target>
44
45 <!-- =================================
46 target: report
41 <!-- conf="*" will copy artifacts defined for each conf in a dir matching conf name -->
42 <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact]-[revision].[ext]"/>
43 </target>
44
45 <!-- =================================
46 target: report
4747 ================================= -->
4848 <target name="report" depends="resolve" description="--> generates a report of dependencies">
4949 <ivy:report todir="${build.dir}"/>
5050 </target>
5151
52 <!-- =================================
53 target: run.dev
52 <!-- =================================
53 target: run.dev
5454 ================================= -->
5555 <target name="run.dev" depends="resolve" description="--> compile and run the project">
56 <mkdir dir="${build.dir}" />
56 <mkdir dir="${build.dir}"/>
5757 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.run.dev.id" includeAntRuntime="false"/>
58 <copy todir="${build.dir}">
59 <fileset dir="${src.dir}" includes="**/*.properties"></fileset>
60 </copy>
58 <copy todir="${build.dir}">
59 <fileset dir="${src.dir}" includes="**/*.properties"></fileset>
60 </copy>
6161 <java classpathref="lib.run.dev.id" classname="example.ConfigurationsExample" fork="true">
62 <arg value="--dev"/>
62 <arg value="--dev"/>
6363 </java>
6464 </target>
65
66 <!-- =================================
67 target: run.prod
65
66 <!-- =================================
67 target: run.prod
6868 ================================= -->
6969 <target name="run.prod" depends="resolve" description="--> compile and run the project">
70 <mkdir dir="${build.dir}" />
70 <mkdir dir="${build.dir}"/>
7171 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.run.prod.id" includeAntRuntime="false"/>
72 <copy todir="${build.dir}">
73 <fileset dir="${src.dir}" includes="**/*.properties"></fileset>
74 </copy>
75 <java classpathref="lib.run.prod.id" classname="example.ConfigurationsExample" fork="true" />
72 <copy todir="${build.dir}">
73 <fileset dir="${src.dir}" includes="**/*.properties"></fileset>
74 </copy>
75 <java classpathref="lib.run.prod.id" classname="example.ConfigurationsExample" fork="true"/>
7676 </target>
77 <!-- =================================
78 target: clean
77
78 <!-- =================================
79 target: clean
7980 ================================= -->
8081 <target name="clean" description="--> clean the project">
8182 <delete includeemptydirs="true">
8283 <fileset dir="${basedir}">
83 <exclude name="src/**" />
84 <exclude name="build.xml" />
85 <exclude name="ivy.xml" />
86 </fileset>
87 </delete>
84 <exclude name="src/**"/>
85 <exclude name="build.xml"/>
86 <exclude name="ivy.xml"/>
87 </fileset>
88 </delete>
8889 </target>
89
90 <!-- =================================
91 target: clean-cache
90
91 <!-- =================================
92 target: clean-cache
9293 ================================= -->
93 <target name="clean-cache" description="--> clean the ivy cache">
94 <ivy:cleancache />
95 </target>
94 <target name="clean-cache" description="--> clean the ivy cache">
95 <ivy:cleancache/>
96 </target>
9697 </project>
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
1919 <ivy-module version="1.0">
2020 <info organisation="org.apache" module="configurations" >
21 <description>
22 This is an example project that aims to demonstrate the usage of the configuration in ivy.
23 This project provide 4 configurations. Each configurations describe the requirement to build or run the project
24 </description>
21 <description>
22 This is an example project that aims to demonstrate the usage of the configuration in ivy.
23 This project provide 4 configurations. Each configurations describe the requirement to build or run the project
24 </description>
2525 </info>
2626 <configurations>
27 <conf name="compile" description="This is this configuration that describes modules need to build our project"/>
28 <conf name="test" extends="compile" description="This is this configuration that describes modules need to run test on our project"/>
29 <conf name="rundev" extends="compile" description="This is this configuration that describes modules need to execute our project in a dev environement"/>
30 <conf name="runprod" extends="compile" description="This is this configuration that describes modules need to execute our project in a production environement"/>
27 <conf name="compile" description="This is this configuration that describes modules need to build our project"/>
28 <conf name="test" extends="compile" description="This is this configuration that describes modules need to run test on our project"/>
29 <conf name="rundev" extends="compile" description="This is this configuration that describes modules need to execute our project in a dev environement"/>
30 <conf name="runprod" extends="compile" description="This is this configuration that describes modules need to execute our project in a production environement"/>
3131 </configurations>
32
32
3333 <dependencies>
34 <!-- this dependency is needed for all configuration -->
35 <dependency org="commons-cli" name="commons-cli" rev="1.0" />
34 <!-- this dependency is needed for all configuration -->
35 <dependency org="commons-cli" name="commons-cli" rev="1.4"/>
3636 <!-- when launching our app in dev mode we use mckoi db and mckoi jdbc client conf="run.dev->embedded, client"-->
37 <dependency org="mckoi" name="mckoi" rev="1.0.2" conf="rundev->default"/>
37 <dependency org="mckoi" name="mckoi" rev="1.0.2" conf="rundev->default"/>
3838 <!-- when launching our app in production environement we needs other jdbc driver -->
39 <dependency org="mm-mysql" name="mm-mysql" rev="2.0.7" conf="runprod->default"/>
40 <!-- junit is only need in the test configuration-->
41 <dependency org="junit" name="junit" rev="3.8" conf="test->default"/>
39 <dependency org="mm-mysql" name="mm-mysql" rev="2.0.7" conf="runprod->default"/>
40 <!-- junit is only need in the test configuration-->
41 <dependency org="junit" name="junit" rev="4.12" conf="test->default"/>
4242 </dependencies>
4343 </ivy-module>
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 driver.class=com.mckoi.JDBCDriver
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package example;
1818
19 import org.apache.commons.cli.CommandLine;
20 import org.apache.commons.cli.CommandLineParser;
21 import org.apache.commons.cli.DefaultParser;
22 import org.apache.commons.cli.Options;
23 import org.apache.commons.cli.ParseException;
24
1925 import java.io.IOException;
2026 import java.util.Properties;
21 import org.apache.commons.cli.CommandLine;
22 import org.apache.commons.cli.CommandLineParser;
23 import org.apache.commons.cli.Options;
24 import org.apache.commons.cli.ParseException;
25 import org.apache.commons.cli.PosixParser;
2627
2728 public final class ConfigurationsExample {
28
29
2930 public static void main(String[] args) {
3031 String jdbcPropToLoad = "prod.properties";
31 CommandLineParser parser = new PosixParser();
32 CommandLineParser parser = new DefaultParser();
3233 Options options = new Options();
33 options.addOption("d", "dev", false,
34 options.addOption("d", "dev", false,
3435 "Dev tag to launch app in dev mode. Means that app will launch embedded mckoi db.");
3536 try {
3637 CommandLine line = parser.parse(options, args);
5556 System.err.println("Jdbc Driver class loading failed. Reason: " + e.getMessage());
5657 e.printStackTrace();
5758 }
58
59
5960 }
60
61
6162 private ConfigurationsExample() {
6263 }
6364 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 driver.class=org.gjt.mm.mysql.Driver
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="filter-framework" default="publish" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="lib" />
21 <property name="build.dir" value="build" />
22 <property name="distrib.dir" location="distrib" />
23 <property name="src.dir" value="src" />
24 <property name="test.dir" value="test" />
25 <property name="build.test.dir" value="${build.dir}/test-classes" />
26 <property name="report.test.dir" value="${build.dir}/test-report" />
27 <property name="revision" value="1.3" />
28
29 <property name="ivy.local.default.root" location="${user.home}/.ivy2/local"/>
30
20 <property name="lib.dir" value="lib"/>
21 <property name="build.dir" value="build"/>
22 <property name="distrib.dir" location="distrib"/>
23 <property name="src.dir" value="src"/>
24 <property name="test.dir" value="test"/>
25 <property name="build.test.dir" value="${build.dir}/test-classes"/>
26 <property name="report.test.dir" value="${build.dir}/test-report"/>
27 <property name="revision" value="1.3"/>
28
29 <property name="ivy.local.default.root" location="${user.home}/.ivy2/local"/>
30
3131 <!-- paths used for compilation and run -->
3232 <path id="compile.path.id">
33 <fileset dir="${lib.dir}/cc-impl" />
34 </path>
35
33 <fileset dir="${lib.dir}/cc-impl"/>
34 </path>
35
3636 <path id="test.path.id">
37 <path location="${build.dir}" />
38 <path location="${build.test.dir}" />
39 <fileset dir="${lib.dir}/test" />
40 </path>
41
42 <!-- =================================
43 target: resolve
37 <path location="${build.dir}"/>
38 <path location="${build.test.dir}"/>
39 <fileset dir="${lib.dir}/test"/>
40 </path>
41
42 <!-- =================================
43 target: resolve
4444 ================================= -->
45 <target name="resolve" description="--> retreive dependencies with ivy">
46 <!-- conf="*" will copie artifacts defined for each conf in a dir matching conf name -->
47 <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact]-[revision].[ext]"/>
45 <target name="resolve" description="--> retrieve dependencies with ivy">
46 <!-- conf="*" will copie artifacts defined for each conf in a dir matching conf name -->
47 <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact]-[revision].[ext]"/>
4848 </target>
49
50 <!-- =================================
51 target: build
49
50 <!-- =================================
51 target: build
5252 ================================= -->
5353 <target name="build" depends="clean, resolve" description="--> compile and jar project">
54 <mkdir dir="${build.dir}" />
55 <mkdir dir="${distrib.dir}"/>
54 <mkdir dir="${build.dir}"/>
55 <mkdir dir="${distrib.dir}"/>
5656 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="compile.path.id" includeAntRuntime="false"/>
57 <jar destfile="${distrib.dir}/filter-api.jar" >
58 <fileset dir="${build.dir}">
59 <include name="filter/*.class"/>
60 </fileset>
61 </jar>
62 <jar destfile="${distrib.dir}/filter-hmimpl.jar" >
63 <fileset dir="${build.dir}">
64 <include name="filter/hmimpl/*.class"/>
65 </fileset>
66 </jar>
67 <jar destfile="${distrib.dir}/filter-ccimpl.jar" >
68 <fileset dir="${build.dir}">
69 <include name="filter/ccimpl/*.class"/>
70 </fileset>
71 </jar>
57 <jar destfile="${distrib.dir}/filter-api.jar" >
58 <fileset dir="${build.dir}">
59 <include name="filter/*.class"/>
60 </fileset>
61 </jar>
62 <jar destfile="${distrib.dir}/filter-hmimpl.jar" >
63 <fileset dir="${build.dir}">
64 <include name="filter/hmimpl/*.class"/>
65 </fileset>
66 </jar>
67 <jar destfile="${distrib.dir}/filter-ccimpl.jar" >
68 <fileset dir="${build.dir}">
69 <include name="filter/ccimpl/*.class"/>
70 </fileset>
71 </jar>
7272 </target>
73
74 <!-- =================================
75 target: test
76 ================================= -->
77 <target name="test" depends="build" description="--> compile and test the project">
78 <mkdir dir="${report.test.dir}"/>
79 <mkdir dir="${build.test.dir}"/>
80
81 <javac srcdir="${test.dir}" destdir="${build.test.dir}" classpathref="test.path.id"/>
82 <junit printsummary="yes" fork="yes" haltonfailure="yes" >
83 <classpath refid="test.path.id"/>
84 <formatter type="plain"/>
85 <batchtest todir="${report.test.dir}" >
86 <fileset dir="${build.test.dir}">
87 <include name="**/**Test.*"/>
88 </fileset>
89 </batchtest>
90 </junit>
91 </target>
92 <!-- =================================
93 target: publish
94 ================================= -->
73
74 <!-- =================================
75 target: test
76 ================================= -->
77 <target name="test" depends="build" description="--> compile and test the project">
78 <mkdir dir="${report.test.dir}"/>
79 <mkdir dir="${build.test.dir}"/>
80
81 <javac srcdir="${test.dir}" destdir="${build.test.dir}" classpathref="test.path.id"/>
82 <junit printsummary="yes" fork="yes" haltonfailure="yes" >
83 <classpath refid="test.path.id"/>
84 <formatter type="plain"/>
85 <batchtest todir="${report.test.dir}" >
86 <fileset dir="${build.test.dir}">
87 <include name="**/**Test.*"/>
88 </fileset>
89 </batchtest>
90 </junit>
91 </target>
92
93 <!-- =================================
94 target: publish
95 ================================= -->
9596 <target name="publish" depends="test" description="--> compile test and publish this project in the local ivy repository">
9697 <property name="revision" value="${revision}"/>
97 <ivy:publish artifactspattern="${distrib.dir}/[artifact].[ext]"
98 resolver="local"
99 pubrevision="${revision}"
100 status="release"/>
101 <echo message="project ${ant.project.name} released with version ${revision}" />
102 </target>
103 <!-- =================================
104 target: clean
98 <ivy:publish artifactspattern="${distrib.dir}/[artifact].[ext]"
99 resolver="local"
100 pubrevision="${revision}"
101 status="release"/>
102 <echo message="project ${ant.project.name} released with version ${revision}"/>
103 </target>
104
105 <!-- =================================
106 target: clean
105107 ================================= -->
106108 <target name="clean" description="--> clean the project">
107109 <delete includeemptydirs="true">
108110 <fileset dir="${basedir}">
109 <exclude name="src/**" />
110 <exclude name="test/**" />
111 <exclude name="build.xml" />
112 <exclude name="ivy.xml" />
113 <exclude name=".*" />
114 </fileset>
115 </delete>
111 <exclude name="src/**"/>
112 <exclude name="test/**"/>
113 <exclude name="build.xml"/>
114 <exclude name="ivy.xml"/>
115 <exclude name=".*"/>
116 </fileset>
117 </delete>
116118 </target>
117
118 <!-- =================================
119 target: clean-cache
119
120 <!-- =================================
121 target: clean-cache
120122 ================================= -->
121 <target name="clean-cache" description="--> clean the ivy cache">
122 <ivy:cleancache />
123 </target>
123 <target name="clean-cache" description="--> clean the ivy cache">
124 <ivy:cleancache/>
125 </target>
124126
125 <!-- =================================
126 target: clean-local
127 ================================= -->
128 <target name="clean-local" description="--> clean the local user repository">
129 <delete dir="${ivy.local.default.root}"/>
130 </target>
127 <!-- =================================
128 target: clean-local
129 ================================= -->
130 <target name="clean-local" description="--> clean the local user repository">
131 <delete dir="${ivy.local.default.root}"/>
132 </target>
131133
132
133 <!-- =================================
134 target: report
134 <!-- =================================
135 target: report
135136 ================================= -->
136137 <target name="report" depends="resolve" description="--> generates a report of dependencies">
137138 <ivy:report todir="${build.dir}"/>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
1919 <info organisation="org.apache" module="filter-framework"/>
2020 <configurations>
21 <conf name="api" description="only provide filter framework API"/>
22 <conf name="homemade-impl" extends="api" description="provide a home made implementation of our api"/>
23 <conf name="cc-impl" extends="api" description="provide an implementation that use apache common collection framework"/>
24 <conf name="test" extends="cc-impl" visibility="private" description="for testing our framework"/>
21 <conf name="api" description="only provide filter framework API"/>
22 <conf name="homemade-impl" extends="api" description="provide a home made implementation of our api"/>
23 <conf name="cc-impl" extends="api" description="provide an implementation that use apache common collection framework"/>
24 <conf name="test" extends="cc-impl" visibility="private" description="for testing our framework"/>
2525 </configurations>
2626 <publications>
27 <artifact name="filter-api" type="jar" conf="api" ext="jar"/>
28 <artifact name="filter-hmimpl" type="jar" conf="homemade-impl" ext="jar"/>
29 <artifact name="filter-ccimpl" type="jar" conf="cc-impl" ext="jar"/>
27 <artifact name="filter-api" type="jar" conf="api" ext="jar"/>
28 <artifact name="filter-hmimpl" type="jar" conf="homemade-impl" ext="jar"/>
29 <artifact name="filter-ccimpl" type="jar" conf="cc-impl" ext="jar"/>
3030 </publications>
3131 <dependencies>
32 <dependency org="commons-collections" name="commons-collections" rev="3.1" conf="cc-impl->default"/>
33 <dependency org="junit" name="junit" rev="3.8" conf="test->default"/>
32 <dependency org="org.apache.commons" name="commons-collections4" rev="4.1" conf="cc-impl->default"/>
33 <dependency org="junit" name="junit" rev="4.12" conf="test->default"/>
3434 </dependencies>
3535 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919
2020 public final class FilterProvider {
21
21
2222 public static IFilter getFilter() {
2323 try {
24 Class clazz = Class.forName("filter.ccimpl.CCFilter");
24 Class<?> clazz = Class.forName("filter.ccimpl.CCFilter");
2525 return (IFilter) clazz.newInstance();
2626 } catch (Exception e) {
2727 try {
28 Class clazz = Class.forName("filter.hmimpl.HMFilter");
28 Class<?> clazz = Class.forName("filter.hmimpl.HMFilter");
2929 return (IFilter) clazz.newInstance();
3030 } catch (Exception e1) {
3131 System.err.println("No filter implementation found in classpath !");
3333 return null;
3434 }
3535 }
36
36
3737 private FilterProvider() {
3838 }
3939 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.ArrayList;
2020 import java.util.Arrays;
2121 import java.util.List;
22 import org.apache.commons.collections.CollectionUtils;
23 import org.apache.commons.collections.Predicate;
22 import org.apache.commons.collections4.CollectionUtils;
23 import org.apache.commons.collections4.Predicate;
2424 import filter.IFilter;
2525
2626 public class CCFilter implements IFilter {
27
27
2828 public String[] filter(String[] values, final String prefix) {
2929 if (values == null) {
3030 return null;
3333 return values;
3434 }
3535
36 List result = new ArrayList(Arrays.asList(values));
37 CollectionUtils.filter(result, new Predicate() {
38 public boolean evaluate(Object o) {
39 return o != null && o.toString().startsWith(prefix);
36 List<String> result = new ArrayList<>(Arrays.asList(values));
37 CollectionUtils.filter(result, new Predicate<String>() {
38 public boolean evaluate(String string) {
39 return string != null && string.startsWith(prefix);
4040 }
4141 });
42 return (String[]) result.toArray(new String[result.size()]);
42 return result.toArray(new String[result.size()]);
4343 }
4444 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import filter.IFilter;
2222
2323 public class HMFilter implements IFilter {
24
24
2525 public String[] filter(String[] values, String prefix) {
2626 if (values == null) {
2727 return null;
2929 if (prefix == null) {
3030 return values;
3131 }
32 List result = new ArrayList();
33 for (int i = 0; i < values.length; i++) {
34 String string = values[i];
35 if (string != null && string.startsWith(prefix)) {
36 result.add(string);
32 List<String> result = new ArrayList<>();
33 for (String value : values) {
34 if (value != null && value.startsWith(prefix)) {
35 result.add(value);
3736 }
3837 }
39 return (String[]) result.toArray(new String[result.size()]);
38 return result.toArray(new String[result.size()]);
4039 }
4140 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="myapp" default="run-cc" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="lib" />
21 <property name="build.dir" value="build" />
22 <property name="src.dir" value="src" />
23
20 <property name="lib.dir" value="lib"/>
21 <property name="build.dir" value="build"/>
22 <property name="src.dir" value="src"/>
23
2424 <!-- paths used for compilation and run -->
2525 <path id="lib.path.id">
26 <fileset dir="${lib.dir}/build" />
27 </path>
26 <fileset dir="${lib.dir}/build"/>
27 </path>
2828 <path id="run.hm.path.id">
29 <path location="${build.dir}" />
30 <fileset dir="${lib.dir}/noexternaljar" />
29 <path location="${build.dir}"/>
30 <fileset dir="${lib.dir}/noexternaljar"/>
3131 </path>
3232 <path id="run.cc.path.id">
33 <path location="${build.dir}" />
34 <fileset dir="${lib.dir}/withexternaljar" />
33 <path location="${build.dir}"/>
34 <fileset dir="${lib.dir}/withexternaljar"/>
3535 </path>
36 <!-- =================================
37 target: resolve
36
37 <!-- =================================
38 target: resolve
3839 ================================= -->
39 <target name="resolve" description="--> retreive dependencies with ivy">
40 <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact].[ext]"/>
41 </target>
42
43 <!-- =================================
44 target: report
40 <target name="resolve" description="--> retrieve dependencies with ivy">
41 <ivy:retrieve pattern="${ivy.lib.dir}/[conf]/[artifact].[ext]"/>
42 </target>
43
44 <!-- =================================
45 target: report
4546 ================================= -->
4647 <target name="report" depends="resolve" description="--> generates a report of dependencies">
4748 <ivy:report todir="${build.dir}"/>
4849 </target>
49
50 <!-- =================================
51 target: build
50
51 <!-- =================================
52 target: build
5253 ================================= -->
5354 <target name="build" depends="resolve" description="--> compile the project">
54 <mkdir dir="${build.dir}" />
55 <mkdir dir="${build.dir}"/>
5556 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id" includeAntRuntime="false"/>
5657 </target>
57
58 <!-- =================================
59 target: run with home made implementation
58
59 <!-- =================================
60 target: run with home made implementation
6061 ================================= -->
6162 <target name="run-hm" depends="build" description="--> run the project with ome made implementation">
6263 <java classpathref="run.hm.path.id" classname="myapp.Main" fork="true"/>
6364 </target>
6465
65 <!-- =================================
66 target: run with ext lib implementation
66 <!-- =================================
67 target: run with ext lib implementation
6768 ================================= -->
6869 <target name="run-cc" depends="build" description="--> run the project with ext lib implementation">
6970 <java classpathref="run.cc.path.id" classname="myapp.Main" fork="true"/>
7071 </target>
71
72 <!-- =================================
73 target: clean
72
73 <!-- =================================
74 target: clean
7475 ================================= -->
7576 <target name="clean" description="--> clean the project">
7677 <delete includeemptydirs="true">
7778 <fileset dir="${basedir}">
78 <exclude name="src/**" />
79 <exclude name="build.xml" />
80 <exclude name="ivy.xml" />
81 <exclude name=".*" />
82 </fileset>
83 </delete>
79 <exclude name="src/**"/>
80 <exclude name="build.xml"/>
81 <exclude name="ivy.xml"/>
82 <exclude name=".*"/>
83 </fileset>
84 </delete>
8485 </target>
85
86 <!-- =================================
87 target: clean-cache
86
87 <!-- =================================
88 target: clean-cache
8889 ================================= -->
89 <target name="clean-cache" description="--> clean the ivy cache">
90 <ivy:cleancache />
91 </target>
90 <target name="clean-cache" description="--> clean the ivy cache">
91 <ivy:cleancache/>
92 </target>
9293 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
1919 <info organisation="org.apache" module="myapp"/>
20
20
2121 <configurations>
22 <conf name="build" visibility="private" description="compilation only need api jar" />
23 <conf name="noexternaljar" description="use only company jar" />
24 <conf name="withexternaljar" description="use company jar and third party jars" />
22 <conf name="build" visibility="private" description="compilation only need api jar"/>
23 <conf name="noexternaljar" description="use only company jar"/>
24 <conf name="withexternaljar" description="use company jar and third party jars"/>
2525 </configurations>
26
26
2727 <dependencies>
2828 <dependency org="org.apache" name="filter-framework" rev="latest.integration" conf="build->api; noexternaljar->homemade-impl; withexternaljar->cc-impl"/>
2929 </dependencies>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import filter.IFilter;
2222
2323 public final class Main {
24
24
2525 public static void main(String[] args) {
2626 String[] toFilter = new String[] {"one", "two", "tree", "four"};
2727 IFilter filter = FilterProvider.getFilter();
2929 String[] filtered = filter.filter(toFilter, "t");
3030 System.out.println("Result :" + Arrays.asList(filtered));
3131 }
32
32
3333 private Main() {
3434 }
3535 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project default="clean">
19
20 <!-- =================================
21 target: clean
19
20 <!-- =================================
21 target: clean
2222 ================================= -->
2323 <target name="clean" description="--> clean directories">
24 <delete includeemptydirs="true">
25 <fileset dir="settings" excludes="ivysettings.*" />
26 </delete>
27 <ant dir="dependee" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false" />
28 <ant dir="depender" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false" />
24 <delete includeemptydirs="true">
25 <fileset dir="settings" excludes="ivysettings.*"/>
26 </delete>
27 <ant dir="dependee" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false"/>
28 <ant dir="depender" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false"/>
2929 </target>
3030
31 <!-- =================================
32 target: all
31 <!-- =================================
32 target: all
3333 ================================= -->
3434 <target name="all" depends="clean" description="--> make the whole example of dependency">
35 <ant dir="dependee" antfile="build.xml" target="publish" inheritall="false" inheritrefs="false" />
36 <ant dir="depender" antfile="build.xml" inheritall="false" inheritrefs="false" />
37 <ant dir="dependee" antfile="build.xml" target="publish" inheritall="false" inheritrefs="false" />
38 <ant dir="depender" antfile="build.xml" inheritall="false" inheritrefs="false" />
35 <ant dir="dependee" antfile="build.xml" target="publish" inheritall="false" inheritrefs="false"/>
36 <ant dir="depender" antfile="build.xml" inheritall="false" inheritrefs="false"/>
37 <ant dir="dependee" antfile="build.xml" target="publish" inheritall="false" inheritrefs="false"/>
38 <ant dir="depender" antfile="build.xml" inheritall="false" inheritrefs="false"/>
3939 </target>
40
40
4141 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="dependee" default="run" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="${basedir}/lib" />
21 <property name="build.dir" value="${basedir}/build" />
22 <property name="classes.dir" value="${build.dir}/classes" />
23 <property name="src.dir" value="${basedir}/src" />
20 <property name="lib.dir" value="${basedir}/lib"/>
21 <property name="build.dir" value="${basedir}/build"/>
22 <property name="classes.dir" value="${build.dir}/classes"/>
23 <property name="src.dir" value="${basedir}/src"/>
2424
2525 <!-- ivy properties used -->
26 <property name="ivy.settings.dir" value="../settings" />
27 <property file="${ivy.settings.dir}/ivysettings.properties" />
28
26 <property name="ivy.settings.dir" value="../settings"/>
27 <property file="${ivy.settings.dir}/ivysettings.properties"/>
28
2929 <!-- paths used for compilation and run -->
3030 <path id="lib.path.id">
31 <fileset dir="${lib.dir}" />
32 </path>
31 <fileset dir="${lib.dir}"/>
32 </path>
3333 <path id="run.path.id">
34 <path refid="lib.path.id" />
35 <path location="${classes.dir}" />
34 <path refid="lib.path.id"/>
35 <path location="${classes.dir}"/>
3636 </path>
37
38 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
39
40 <!-- =================================
41 target: resolve
37
38 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml"/>
39
40 <!-- =================================
41 target: resolve
4242 ================================= -->
4343 <target name="resolve" description="--> resolve and retrieve dependencies with ivy">
44 <ivy:retrieve />
44 <ivy:retrieve/>
4545 </target>
46
47 <!-- =================================
48 target: report
46
47 <!-- =================================
48 target: report
4949 ================================= -->
5050 <target name="report" depends="resolve" description="--> generates a report of dependencies">
5151 <ivy:report todir="${build.dir}"/>
5252 </target>
53
54 <!-- =================================
55 target: compile
53
54 <!-- =================================
55 target: compile
5656 ================================= -->
5757 <target name="compile" depends="resolve" description="--> description">
58 <mkdir dir="${classes.dir}" />
58 <mkdir dir="${classes.dir}"/>
5959 <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="lib.path.id" includeAntRuntime="false"/>
6060 </target>
61
62 <!-- =================================
61
62 <!-- =================================
6363 target: run
6464 ================================= -->
6565 <target name="run" depends="compile" description="--> compile and run the project">
6666 <java classpathref="run.path.id" classname="standalone.Main"/>
6767 </target>
68
69 <!-- =================================
70 target: jar
68
69 <!-- =================================
70 target: jar
7171 ================================= -->
7272 <target name="jar" depends="compile" description="--> make a jar file for this project">
7373 <propertyfile file="${classes.dir}/version.properties">
74 <entry key="version" type="int" operation="+" default="0" />
75 </propertyfile>
76 <property file="${classes.dir}/version.properties" />
74 <entry key="version" type="int" operation="+" default="0"/>
75 </propertyfile>
76 <property file="${classes.dir}/version.properties"/>
7777 <jar destfile="${build.dir}/${ant.project.name}.jar">
78 <fileset dir="${classes.dir}" />
78 <fileset dir="${classes.dir}"/>
7979 </jar>
8080 </target>
8181
82 <!-- =================================
83 target: publish
82 <!-- =================================
83 target: publish
8484 ================================= -->
8585 <target name="publish" depends="jar" description="--> publish this project in the ivy repository">
8686 <property name="revision" value="${version}"/>
8787 <delete file="${build.dir}/ivy.xml"/>
88 <ivy:publish artifactspattern="${build.dir}/[artifact].[ext]"
89 resolver="projects"
90 pubrevision="${revision}"
91 status="release"
92 />
93 <echo message="project ${ant.project.name} released with version ${revision}" />
88 <ivy:publish artifactspattern="${build.dir}/[artifact].[ext]"
89 resolver="projects"
90 pubrevision="${revision}"
91 status="release"/>
92 <echo message="project ${ant.project.name} released with version ${revision}"/>
9493 </target>
9594
96
97 <!-- =================================
98 target: clean
95 <!-- =================================
96 target: clean
9997 ================================= -->
10098 <target name="clean" description="--> clean the project">
10199 <delete includeemptydirs="true">
102100 <fileset dir="${basedir}">
103 <exclude name="src/**" />
104 <exclude name="build.xml" />
105 <exclude name="ivy.xml" />
106 </fileset>
107 </delete>
101 <exclude name="src/**"/>
102 <exclude name="build.xml"/>
103 <exclude name="ivy.xml"/>
104 </fileset>
105 </delete>
108106 </target>
109107 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
1919 <info organisation="org.apache" module="dependee"/>
2020 <dependencies>
21 <dependency org="commons-lang" name="commons-lang" rev="2.0"/>
21 <dependency org="commons-lang" name="commons-lang" rev="2.6"/>
2222 </dependencies>
2323 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535 String version = p.getProperty("version");
3636 if (version != null) {
3737 return String.valueOf(Integer.parseInt(version));
38 }
38 }
3939 } catch (Exception e) {
4040 e.printStackTrace();
4141 }
4242 return null;
4343 }
44
44
4545 /**
4646 * Return the same string with all words capitalized.
4747 * @param str the string conatining the words to capitalize
4848 * @return null if the string was null, the string with all words capitalized otherwise
4949 */
5050 public static String capitalizeWords(String str) {
51 System.out.println(" [" + Main.class.getName() + "] capitalizing string \""
51 System.out.println(" [" + Main.class.getName() + "] capitalizing string \""
5252 + str + "\" using " + WordUtils.class.getName());
5353 return WordUtils.capitalizeFully(str);
5454 }
5757 System.out.println("standard message : " + message);
5858 System.out.println("capitalized message : " + capitalizeWords(message));
5959 }
60
60
6161 private Main() {
6262 }
6363 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="depender" default="run" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="${basedir}/lib" />
21 <property name="build.dir" value="${basedir}/build" />
22 <property name="classes.dir" value="${build.dir}/classes" />
23 <property name="src.dir" value="${basedir}/src" />
20 <property name="lib.dir" value="${basedir}/lib"/>
21 <property name="build.dir" value="${basedir}/build"/>
22 <property name="classes.dir" value="${build.dir}/classes"/>
23 <property name="src.dir" value="${basedir}/src"/>
2424
2525 <!-- ivy properties used -->
26 <property name="ivy.settings.dir" value="../settings" />
27 <property file="${ivy.settings.dir}/ivysettings.properties" />
28
26 <property name="ivy.settings.dir" value="../settings"/>
27 <property file="${ivy.settings.dir}/ivysettings.properties"/>
28
2929 <!-- paths used for compilation and run -->
3030 <path id="lib.path.id">
31 <fileset dir="${lib.dir}" />
32 </path>
31 <fileset dir="${lib.dir}"/>
32 </path>
3333 <path id="run.path.id">
34 <path refid="lib.path.id" />
35 <path location="${classes.dir}" />
34 <path refid="lib.path.id"/>
35 <path location="${classes.dir}"/>
3636 </path>
3737
38 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
39
40 <!-- =================================
41 target: resolve
38 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml"/>
39
40 <!-- =================================
41 target: resolve
4242 ================================= -->
4343 <target name="resolve" description="--> resolve and retrieve dependencies with ivy">
44 <ivy:retrieve />
44 <ivy:retrieve/>
4545 </target>
46
47 <!-- =================================
48 target: report
46
47 <!-- =================================
48 target: report
4949 ================================= -->
5050 <target name="report" depends="resolve" description="--> generates a report of dependencies">
5151 <ivy:report todir="${build.dir}" dot="true"/>
5252 </target>
53
54 <!-- =================================
53
54 <!-- =================================
5555 target: gen-graph
5656 ================================= -->
5757 <target name="gen-graph" depends="report" description="--> generates a graph of dependencies (requires dot in your path - see http://www.graphviz.org/)">
58 <property name="dot.file" value="${build.dir}/apache-depending-default.dot" />
59 <property name="ivygraph.output.file" value="${build.dir}/graph.png" />
60 <exec executable="dot">
61 <arg line="-T png -o ${ivygraph.output.file} ${dot.file}" />
62 </exec>
58 <property name="dot.file" value="${build.dir}/apache-depending-default.dot"/>
59 <property name="ivygraph.output.file" value="${build.dir}/graph.png"/>
60 <exec executable="dot">
61 <arg line="-T png -o ${ivygraph.output.file} ${dot.file}"/>
62 </exec>
6363 </target>
64
65 <!-- =================================
66 target: compile
64
65 <!-- =================================
66 target: compile
6767 ================================= -->
6868 <target name="compile" depends="resolve" description="--> description">
69 <mkdir dir="${classes.dir}" />
69 <mkdir dir="${classes.dir}"/>
7070 <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="lib.path.id" includeAntRuntime="false"/>
7171 </target>
72
73 <!-- =================================
72
73 <!-- =================================
7474 target: run
7575 ================================= -->
7676 <target name="run" depends="clean, compile" description="--> compile and run the project">
7777 <java classpathref="run.path.id" classname="depending.Main"/>
7878 </target>
79
80 <!-- =================================
81 target: clean
79
80 <!-- =================================
81 target: clean
8282 ================================= -->
8383 <target name="clean" description="--> clean the project">
8484 <delete includeemptydirs="true">
8585 <fileset dir="${basedir}">
86 <exclude name="src/**" />
87 <exclude name="build.xml" />
88 <exclude name="ivy.xml" />
89 </fileset>
90 </delete>
86 <exclude name="src/**"/>
87 <exclude name="build.xml"/>
88 <exclude name="ivy.xml"/>
89 </fileset>
90 </delete>
9191 </target>
9292 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
1919 <info organisation="org.apache" module="depender"/>
2020 <dependencies>
21 <dependency name="dependee" rev="latest.integration" />
21 <dependency name="dependee" rev="latest.integration"/>
2222 </dependencies>
2323 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 public static void main(String[] args) {
2424 String standaloneVersion = standalone.Main.getVersion();
2525 if (standaloneVersion != null) {
26 System.out.println("you are using version " + standaloneVersion
26 System.out.println("you are using version " + standaloneVersion
2727 + " of class " + standalone.Main.class.getName());
2828 } else {
2929 System.err.println("failed to get version of " + standalone.Main.class.getName());
3030 }
31 String message = "i am " + Main.class.getName()
31 String message = "i am " + Main.class.getName()
3232 + " and " + standalone.Main.class.getName() + " will do the job for me";
3333 System.out.println("standard message : " + message);
3434 System.out.println("capitalized message : " + standalone.Main.capitalizeWords(message));
3535 }
36
36
3737 private Main() {
3838 }
3939 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 repository.dir=${ivy.settings.dir}/repository
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <properties file="${ivy.settings.dir}/ivysettings.properties"/>
20 <settings defaultResolver="libraries" />
21 <caches defaultCacheDir="${ivy.settings.dir}/ivy-cache" />
22 <resolvers>
23 <filesystem name="projects">
24 <artifact pattern="${repository.dir}/[artifact]-[revision].[ext]" />
25 <ivy pattern="${repository.dir}/[module]-[revision].xml" />
26 </filesystem>
27 <ibiblio name="libraries" m2compatible="true" usepoms="false" />
28 </resolvers>
29 <modules>
30 <module organisation="org.apache" name="dependee" resolver="projects"/>
31 </modules>
19 <properties file="${ivy.settings.dir}/ivysettings.properties"/>
20 <settings defaultResolver="libraries"/>
21 <caches defaultCacheDir="${ivy.settings.dir}/ivy-cache"/>
22 <resolvers>
23 <filesystem name="projects">
24 <artifact pattern="${repository.dir}/[artifact]-[revision].[ext]"/>
25 <ivy pattern="${repository.dir}/[module]-[revision].xml"/>
26 </filesystem>
27 <ibiblio name="libraries" m2compatible="true" usepoms="false"/>
28 </resolvers>
29 <modules>
30 <module organisation="org.apache" name="dependee" resolver="projects"/>
31 </modules>
3232 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project default="clean-all" xmlns:ivy="antlib:org.apache.ivy.ant">
19
20 <!-- =================================
21 target: clean
19
20 <!-- =================================
21 target: clean
2222 ================================= -->
2323 <target name="clean" description="--> clean directories">
24 <ant dir="project" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false" />
24 <ant dir="project" antfile="build.xml" target="clean" inheritall="false" inheritrefs="false"/>
2525 </target>
26
27 <!-- =================================
28 target: clean-cache
26
27 <!-- =================================
28 target: clean-cache
2929 ================================= -->
30 <target name="clean-cache" description="--> clean the ivy cache">
31 <property name="ivy.settings.dir" value="settings" />
32 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
33 <ivy:cleancache />
34 </target>
35
36 <target name="clean-all" depends="clean, clean-cache" description="--> clean directories and ivy cache"/>
30 <target name="clean-cache" description="--> clean the ivy cache">
31 <property name="ivy.settings.dir" value="settings"/>
32 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml"/>
33 <ivy:cleancache/>
34 </target>
35
36 <target name="clean-all" depends="clean,clean-cache" description="--> clean directories and ivy cache"/>
3737 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="dual-ivy" default="run" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="${basedir}/lib" />
21 <property name="build.dir" value="${basedir}/build" />
22 <property name="src.dir" value="${basedir}/src" />
23
20 <property name="lib.dir" value="${basedir}/lib"/>
21 <property name="build.dir" value="${basedir}/build"/>
22 <property name="src.dir" value="${basedir}/src"/>
23
2424 <!-- ivy properties used -->
25 <property name="ivy.settings.dir" value="../settings" />
25 <property name="ivy.settings.dir" value="../settings"/>
2626
27 <!-- paths used for compilation and run -->
27 <!-- paths used for compilation and run -->
2828 <path id="lib.path.id">
29 <fileset dir="${lib.dir}" />
30 </path>
29 <fileset dir="${lib.dir}"/>
30 </path>
3131 <path id="run.path.id">
32 <path refid="lib.path.id" />
33 <path location="${build.dir}" />
32 <path refid="lib.path.id"/>
33 <path location="${build.dir}"/>
3434 </path>
35
36 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml" />
37
38 <!-- =================================
39 target: resolve
35
36 <ivy:settings file="${ivy.settings.dir}/ivysettings.xml"/>
37
38 <!-- =================================
39 target: resolve
4040 ================================= -->
4141 <target name="resolve" description="--> resolve and retrieve dependencies with ivy">
42 <ivy:retrieve />
42 <ivy:retrieve/>
4343 </target>
44
45 <!-- =================================
46 target: report
44
45 <!-- =================================
46 target: report
4747 ================================= -->
4848 <target name="report" depends="resolve" description="--> generates a report of dependencies">
4949 <ivy:report todir="${build.dir}"/>
5050 </target>
51
52 <!-- =================================
51
52 <!-- =================================
5353 target: run
5454 ================================= -->
5555 <target name="run" depends="resolve" description="--> compile and run the project">
56 <mkdir dir="${build.dir}" />
56 <mkdir dir="${build.dir}"/>
5757 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id" includeAntRuntime="false"/>
58 <java classpathref="run.path.id" classname="example.Hello"/>
58 <java classpathref="run.path.id" classname="example.HelloIvy"/>
5959 </target>
60
61 <!-- =================================
62 target: clean
60
61 <!-- =================================
62 target: clean
6363 ================================= -->
6464 <target name="clean" description="--> clean the project">
6565 <delete includeemptydirs="true">
6666 <fileset dir="${basedir}">
67 <exclude name="src/**" />
68 <exclude name="build.xml" />
69 <exclude name="ivy.xml" />
70 </fileset>
71 </delete>
67 <exclude name="src/**"/>
68 <exclude name="build.xml"/>
69 <exclude name="ivy.xml"/>
70 </fileset>
71 </delete>
7272 </target>
73
74 <!-- =================================
75 target: clean-cache
73
74 <!-- =================================
75 target: clean-cache
7676 ================================= -->
77 <target name="clean-cache" description="--> clean the ivy cache">
78 <ivy:cleancache />
79 </target>
77 <target name="clean-cache" description="--> clean the ivy cache">
78 <ivy:cleancache/>
79 </target>
8080 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
1919 <info organisation="org.apache" module="hello-ivy"/>
2020 <dependencies>
2121 <dependency org="commons-httpclient" name="commons-httpclient" rev="2.0.2"/>
22 <dependency org="commons-lang" name="commons-lang" rev="2.0"/>
22 <dependency org="commons-lang" name="commons-lang" rev="2.6"/>
2323 </dependencies>
2424 </ivy-module>
+0
-51
src/example/dual/project/src/example/Hello.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package example;
18
19 import org.apache.commons.httpclient.HttpClient;
20 import org.apache.commons.httpclient.methods.HeadMethod;
21 import org.apache.commons.lang.WordUtils;
22
23 /**
24 * Simple hello world example to show how easy it is to retrieve libs with ivy,
25 * including transitive dependencies
26 */
27 public final class Hello {
28 public static void main(String[] args) throws Exception {
29 String message = "hello ivy !";
30 System.out.println("standard message : " + message);
31 System.out.println("capitalized by " + WordUtils.class.getName()
32 + " : " + WordUtils.capitalizeFully(message));
33
34 HttpClient client = new HttpClient();
35 HeadMethod head = new HeadMethod("http://www.ibiblio.org/");
36 client.executeMethod(head);
37
38 int status = head.getStatusCode();
39 System.out.println("head status code with httpclient: " + status);
40 head.releaseConnection();
41
42 System.out.println(
43 "now check if httpclient dependency on commons-logging has been realized");
44 Class clss = Class.forName("org.apache.commons.logging.Log");
45 System.out.println("found logging class in classpath: " + clss);
46 }
47
48 private Hello() {
49 }
50 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package example;
18
19 import org.apache.commons.httpclient.HttpClient;
20 import org.apache.commons.httpclient.methods.HeadMethod;
21 import org.apache.commons.lang.WordUtils;
22
23 /**
24 * Simple hello world example to show how easy it is to retrieve libs with ivy,
25 * including transitive dependencies
26 */
27 public final class HelloIvy {
28 public static void main(String[] args) throws Exception {
29 String message = "Hello Ivy!";
30 System.out.println("standard message : " + message);
31 System.out.println("capitalized by " + WordUtils.class.getName()
32 + " : " + WordUtils.capitalizeFully(message));
33
34 HttpClient client = new HttpClient();
35 HeadMethod head = new HeadMethod("http://www.ibiblio.org/");
36 client.executeMethod(head);
37
38 int status = head.getStatusCode();
39 System.out.println("head status code with httpclient: " + status);
40 head.releaseConnection();
41
42 System.out.println(
43 "now check if httpclient dependency on commons-logging has been realized");
44 Class<?> clss = Class.forName("org.apache.commons.logging.Log");
45 System.out.println("found logging class in classpath: " + clss);
46 }
47
48 private HelloIvy() {
49 }
50 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
20 organisation="commons-httpclient"
21 module="commons-httpclient"
22 revision="2.0.2"
23 status="release"
24 publication="20041010174300"/>
19 <info organisation="commons-httpclient"
20 module="commons-httpclient"
21 revision="2.0.2"
22 status="release"
23 publication="20041010174300"/>
2524 <dependencies>
2625 <dependency org="commons-logging" name="commons-logging" rev="1.0.4" conf="default"/>
2726 </dependencies>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
1919 <settings defaultResolver="dual-example"/>
2020 <resolvers>
2121 <dual name="dual-example">
2222 <filesystem name="ivys">
23 <ivy pattern="${ivy.settings.dir}/../repository/[module]-ivy-[revision].xml" />
23 <ivy pattern="${ivy.settings.dir}/../repository/[module]-ivy-[revision].xml"/>
2424 </filesystem>
25 <ibiblio name="ibiblio" m2compatible="true" usepoms="false" />
25 <ibiblio name="ibiblio" m2compatible="true" usepoms="false"/>
2626 </dual>
2727 </resolvers>
2828 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="go-ivy" default="go" xmlns:ivy="antlib:org.apache.ivy.ant">
19 <!--
20 this build file is a self contained project: it doesn't require anything else
19 <!--
20 this build file is a self contained project: it doesn't require anything else
2121 that ant 1.6.2 or greater and java 1.4 or greater properly installed.
22
22
2323 It is used to showcase how easy and straightforward it can be to use Ivy.
24
24
2525 This is not an example of the best pratice to use in a project, especially
2626 for the java source code "generation" :-) (see generate-src target)
27
27
2828 To run copy this file in an empty directory, open a shell or a command window
29 in this directory and run "ant". It will download ivy and then use it to resolve
29 in this directory and run "ant". It will download ivy and then use it to resolve
3030 the dependency of the class which is itself "contained" in this build script.
31
31
3232 After a successful build run "ant" again and you will see the build will be
3333 much faster.
34
34
3535 More information can be found at http://ant.apache.org/ivy/
3636 -->
37
38 <!-- here is the version of ivy we will use. change this property to try a newer
37
38 <!-- here is the version of ivy we will use. change this property to try a newer
3939 version if you want -->
40 <property name="ivy.install.version" value="2.0.0-beta1" />
41 <property name="ivy.jar.dir" value="${basedir}/ivy" />
42 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
40 <property name="ivy.install.version" value="2.0.0-beta1"/>
41 <property name="ivy.jar.dir" value="${basedir}/ivy"/>
42 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
4343
44 <property name="build.dir" value="build" />
45 <property name="src.dir" value="src" />
46
47
44 <property name="build.dir" value="build"/>
45 <property name="src.dir" value="src"/>
46
4847 <target name="download-ivy" unless="skip.download">
49 <mkdir dir="${ivy.jar.dir}"/>
50 <!-- download Ivy from web site so that it can be used even without any special installation -->
51 <echo message="installing ivy..."/>
52 <get src="https://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar"
53 dest="${ivy.jar.file}" usetimestamp="true"/>
48 <mkdir dir="${ivy.jar.dir}"/>
49 <!-- download Ivy from web site so that it can be used even without any special installation -->
50 <echo message="installing ivy..."/>
51 <get src="https://repo1.maven.org/maven2/org/apache/ivy/ivy/${ivy.install.version}/ivy-${ivy.install.version}.jar"
52 dest="${ivy.jar.file}" usetimestamp="true"/>
5453 </target>
55
56 <!-- =================================
57 target: install-ivy
58 this target is not necessary if you put ivy.jar in your ant lib directory
59 if you already have ivy in your ant lib, you can simply remove this
60 target and the dependency the 'go' target has on it
54
55 <!-- =================================
56 target: install-ivy
57 this target is not necessary if you put ivy.jar in your ant lib directory
58 if you already have ivy in your ant lib, you can simply remove this
59 target and the dependency the 'go' target has on it
60 ================================= -->
61 <target name="install-ivy" depends="download-ivy" description="--> install ivy">
62 <!-- try to load ivy here from local ivy dir, in case the user has not already dropped
63 it into ant's lib dir (note that the latter copy will always take precedence).
64 We will not fail as long as the ivy jar is in at least one of ant's lib dir or
65 the local lib dir. -->
66 <path id="ivy.lib.path">
67 <pathelement location="${ivy.jar.file}"/>
68 </path>
69 <taskdef resource="org/apache/ivy/ant/antlib.xml"
70 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
71 </target>
72
73 <!-- =================================
74 target: go
75 Go ivy, go!
6176 ================================= -->
62 <target name="install-ivy" depends="download-ivy" description="--> install ivy">
63 <!-- try to load ivy here from local ivy dir, in case the user has not already dropped
64 it into ant's lib dir (note that the latter copy will always take precedence).
65 We will not fail as long as the ivy jar is in at least one of ant's lib dir or
66 the local lib dir. -->
67 <path id="ivy.lib.path">
68 <pathelement location="${ivy.jar.file}"/>
69 </path>
70 <taskdef resource="org/apache/ivy/ant/antlib.xml"
71 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
72 </target>
73
74 <!-- =================================
75 target: go
76 Go ivy, go!
77 ================================= -->
78 <target name="go" depends="install-ivy, generate-src"
77 <target name="go" depends="install-ivy, generate-src"
7978 description="--> resolve dependencies, compile and run the project">
80 <echo message="using ivy to resolve commons-lang 2.1..."/>
81 <!-- here comes the magic line: asks ivy to resolve a dependency on
79 <echo message="using ivy to resolve commons-lang 2.1..."/>
80 <!-- here comes the magic line: asks ivy to resolve a dependency on
8281 commons-lang 2.1 and to build an ant path with it from its cache -->
83 <ivy:cachepath organisation="commons-lang" module="commons-lang" revision="2.1"
82 <ivy:cachepath organisation="commons-lang" module="commons-lang" revision="2.1"
8483 pathid="lib.path.id" inline="true"/>
85
86 <echo message="compiling..."/>
87 <mkdir dir="${build.dir}" />
84
85 <echo message="compiling..."/>
86 <mkdir dir="${build.dir}"/>
8887 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id" includeAntRuntime="false"/>
89
90 <echo>
88
89 <echo>
9190 We are now ready to execute our simple program with its dependency on commons-lang.
9291 Let's go!
93 </echo>
92 </echo>
9493 <java classname="example.Hello">
9594 <classpath>
96 <path refid="lib.path.id" />
97 <path location="${build.dir}" />
95 <path refid="lib.path.id"/>
96 <path location="${build.dir}"/>
9897 </classpath>
9998 </java>
10099 </target>
101100
102 <!-- =================================
103 target: generate-src
104 'Generates' the class source. It actually just echo a simple java
105 source code to a file. In real life this file would already be
106 present on your file system, and this target wouldn't be necessary.
101 <!-- =================================
102 target: generate-src
103 'Generates' the class source. It actually just echo a simple java
104 source code to a file. In real life this file would already be
105 present on your file system, and this target wouldn't be necessary.
107106 ================================= -->
108107 <target name="generate-src">
109 <mkdir dir="${src.dir}/example" />
108 <mkdir dir="${src.dir}/example"/>
110109 <echo file="${src.dir}/example/Hello.java">
111110 package example;
112111
116115 public static void main(String[] args) {
117116 String message = "hello ivy !";
118117 System.out.println("standard message : " + message);
119 System.out.println("capitalized by " + WordUtils.class.getName()
118 System.out.println("capitalized by " + WordUtils.class.getName()
120119 + " : " + WordUtils.capitalizeFully(message));
121120 }
122121 }
123122 </echo>
124123 </target>
125
126 <!-- =================================
127 target: clean
124
125 <!-- =================================
126 target: clean
128127 ================================= -->
129128 <target name="clean" description="--> clean the project">
130129 <delete includeemptydirs="true" quiet="true">
131 <fileset dir="${src.dir}" />
132 <fileset dir="${build.dir}" />
133 </delete>
130 <fileset dir="${src.dir}"/>
131 <fileset dir="${build.dir}"/>
132 </delete>
134133 </target>
135
136 <!-- =================================
137 target: clean-ivy
134
135 <!-- =================================
136 target: clean-ivy
138137 ================================= -->
139 <target name="clean-ivy" description="--> clean the ivy installation">
140 <delete dir="${ivy.jar.dir}"/>
141 </target>
142
143 <!-- =================================
144 target: clean-cache
138 <target name="clean-ivy" description="--> clean the ivy installation">
139 <delete dir="${ivy.jar.dir}"/>
140 </target>
141
142 <!-- =================================
143 target: clean-cache
145144 ================================= -->
146 <target name="clean-cache" depends="install-ivy"
147 description="--> clean the ivy cache">
148 <ivy:cleancache />
149 </target>
145 <target name="clean-cache" depends="install-ivy"
146 description="--> clean the ivy cache">
147 <ivy:cleancache/>
148 </target>
150149 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="hello-ivy" default="run" xmlns:ivy="antlib:org.apache.ivy.ant">
1919 <!-- some variables used -->
20 <property name="lib.dir" value="lib" />
21 <property name="build.dir" value="build" />
22 <property name="src.dir" value="src" />
23
20 <property name="lib.dir" value="lib"/>
21 <property name="build.dir" value="build"/>
22 <property name="src.dir" value="src"/>
23
2424 <!-- paths used for compilation and run -->
2525 <path id="lib.path.id">
26 <fileset dir="${lib.dir}" />
27 </path>
26 <fileset dir="${lib.dir}"/>
27 </path>
2828 <path id="run.path.id">
29 <path refid="lib.path.id" />
30 <path location="${build.dir}" />
29 <path refid="lib.path.id"/>
30 <path location="${build.dir}"/>
3131 </path>
32
33 <!-- =================================
34 target: resolve
32
33 <!-- =================================
34 target: resolve
3535 ================================= -->
3636 <target name="resolve" description="--> retreive dependencies with ivy">
3737 <ivy:retrieve/>
38 </target>
39
40 <!-- =================================
41 target: report
38 </target>
39
40 <!-- =================================
41 target: report
4242 ================================= -->
4343 <target name="report" depends="resolve" description="--> generates a report of dependencies">
4444 <ivy:report todir="${build.dir}"/>
4545 </target>
4646
47 <!-- =================================
47 <!-- =================================
4848 target: run
4949 ================================= -->
5050 <target name="run" depends="resolve" description="--> compile and run the project">
51 <mkdir dir="${build.dir}" />
51 <mkdir dir="${build.dir}"/>
5252 <javac srcdir="${src.dir}" destdir="${build.dir}" classpathref="lib.path.id" includeAntRuntime="false"/>
53 <property name="msg" value="hello ivy !"/>
54 <java classpathref="run.path.id" classname="example.Hello">
55 <arg value="-message"/>
56 <arg value="${msg}"/>
57 </java>
53 <property name="msg" value="hello ivy !"/>
54 <java classpathref="run.path.id" classname="example.HelloConsole">
55 <arg value="-message"/>
56 <arg value="${msg}"/>
57 </java>
5858 </target>
5959
60 <!-- =================================
61 target: clean
60 <!-- =================================
61 target: clean
6262 ================================= -->
6363 <target name="clean" description="--> clean the project">
6464 <delete includeemptydirs="true">
6565 <fileset dir="${basedir}">
66 <exclude name="src/**" />
67 <exclude name="build.xml" />
68 <exclude name="ivy.xml" />
69 </fileset>
70 </delete>
66 <exclude name="src/**"/>
67 <exclude name="build.xml"/>
68 <exclude name="ivy.xml"/>
69 </fileset>
70 </delete>
7171 </target>
72
73 <!-- =================================
74 target: clean-cache
72
73 <!-- =================================
74 target: clean-cache
7575 ================================= -->
76 <target name="clean-cache" description="--> clean the ivy cache">
77 <ivy:cleancache />
78 </target>
76 <target name="clean-cache" description="--> clean the ivy cache">
77 <ivy:cleancache/>
78 </target>
7979 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="2.0">
1919 <info organisation="org.apache" module="hello-ivy"/>
2020 <dependencies>
21 <dependency org="commons-lang" name="commons-lang" rev="2.0"/>
22 <dependency org="commons-cli" name="commons-cli" rev="1.0"/>
21 <dependency org="commons-lang" name="commons-lang" rev="2.6"/>
22 <dependency org="commons-cli" name="commons-cli" rev="1.4"/>
2323 </dependencies>
2424 </ivy-module>
+0
-51
src/example/hello-ivy/src/example/Hello.java less more
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package example;
18
19 import org.apache.commons.cli.CommandLine;
20 import org.apache.commons.cli.CommandLineParser;
21 import org.apache.commons.cli.GnuParser;
22 import org.apache.commons.cli.Option;
23 import org.apache.commons.cli.OptionBuilder;
24 import org.apache.commons.cli.Options;
25 import org.apache.commons.lang.WordUtils;
26
27 /**
28 * Simple example to show how easy it is to retrieve transitive libs with ivy !!!
29 */
30 public final class Hello {
31 public static void main(String[] args) throws Exception {
32 Option msg = OptionBuilder.withArgName("msg")
33 .hasArg()
34 .withDescription("the message to capitalize")
35 .create("message");
36 Options options = new Options();
37 options.addOption(msg);
38
39 CommandLineParser parser = new GnuParser();
40 CommandLine line = parser.parse(options, args);
41
42 String message = line.getOptionValue("message", "hello ivy !");
43 System.out.println("standard message : " + message);
44 System.out.println("capitalized by " + WordUtils.class.getName()
45 + " : " + WordUtils.capitalizeFully(message));
46 }
47
48 private Hello() {
49 }
50 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package example;
18
19 import org.apache.commons.cli.CommandLine;
20 import org.apache.commons.cli.CommandLineParser;
21 import org.apache.commons.cli.DefaultParser;
22 import org.apache.commons.cli.Option;
23 import org.apache.commons.cli.Options;
24 import org.apache.commons.lang.WordUtils;
25
26 /**
27 * Simple example to show how easy it is to retrieve transitive libs with ivy !!!
28 */
29 public final class HelloConsole {
30 public static void main(String[] args) throws Exception {
31 Option msg = Option.builder("m")
32 .longOpt("message")
33 .hasArg()
34 .desc("the message to capitalize")
35 .build();
36 Options options = new Options();
37 options.addOption(msg);
38
39 CommandLineParser parser = new DefaultParser();
40 CommandLine line = parser.parse(options, args);
41
42 String message = line.getOptionValue("m", "Hello Ivy!");
43 System.out.println("standard message : " + message);
44 System.out.println("capitalized by " + WordUtils.class.getName()
45 + " : " + WordUtils.capitalizeFully(message));
46 }
47
48 private HelloConsole() {
49 }
50 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
18 <project name="all"
19 xmlns:ivy="antlib:org.apache.ivy.ant">
20
21 <property name="ivy.jar.dir" value="${user.home}/.ivy2/jars" />
22 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
18 <project name="all" xmlns:ivy="antlib:org.apache.ivy.ant">
2319
24 <property name="build.dir" value="build" />
25 <property name="src.dir" value="src" />
26
27
28 <!-- =================================
29 target: load-ivy
30 this target is not necessary if you put ivy.jar in your ant lib directory
31 if you already have ivy 1.4 in your ant lib, you can simply remove this
32 target
20 <property name="ivy.jar.dir" value="${user.home}/.ivy2/jars"/>
21 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
22
23 <property name="build.dir" value="build"/>
24 <property name="src.dir" value="src"/>
25
26
27 <!-- =================================
28 target: load-ivy
29 this target is not necessary if you put ivy.jar in your ant lib directory
30 if you already have ivy 1.4 in your ant lib, you can simply remove this
31 target
3332 ================================= -->
3433 <target name="load-ivy">
35 <!-- try to load ivy here from home ivy dir, in case the user has not already dropped
36 it into ant's lib dir (note that the latter copy will always take precedence).
37 We will not fail as long as ivy home lib dir exists (it may be empty) and
38 ivy is in at least one of ant's lib dir or the ivy home lib dir. -->
39 <path id="ivy.lib.path">
40 <pathelement location="${ivy.jar.file}"/>
41 </path>
42 <taskdef resource="org/apache/ivy/ant/antlib.xml"
43 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
44 </target>
45
46 <target name="buildlist" depends="load-ivy">
47 <ivy:buildlist reference="build-path">
48 <fileset dir="projects" includes="**/build.xml"/>
49 </ivy:buildlist>
34 <!-- try to load ivy here from home ivy dir, in case the user has not already dropped
35 it into ant's lib dir (note that the latter copy will always take precedence).
36 We will not fail as long as ivy home lib dir exists (it may be empty) and
37 ivy is in at least one of ant's lib dir or the ivy home lib dir. -->
38 <path id="ivy.lib.path">
39 <pathelement location="${ivy.jar.file}"/>
40 </path>
41 <taskdef resource="org/apache/ivy/ant/antlib.xml"
42 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
43 </target>
44
45 <target name="buildlist" depends="load-ivy">
46 <ivy:buildlist reference="build-path">
47 <fileset dir="projects" includes="**/build.xml"/>
48 </ivy:buildlist>
49 </target>
50
51 <target name="publish-all" depends="buildlist"
52 description="compile, jar and publish all projects in the right order">
53 <subant target="publish" buildpathref="build-path"/>
54 </target>
55
56 <target name="clean-all" depends="buildlist" description="clean all projects">
57 <subant target="clean" buildpathref="build-path"/>
58 </target>
59
60 <target name="clean" depends="clean-all, load-ivy"
61 description="clean tutorial: delete repository, ivy cache, and all projects">
62 <delete dir="repository"/>
63 <ivy:cleancache/>
5064 </target>
51
52 <target name="publish-all" depends="buildlist"
53 description="compile, jar and publish all projects in the right order">
54 <subant target="publish" buildpathref="build-path" />
55 </target>
56
57 <target name="clean-all" depends="buildlist" description="clean all projects">
58 <subant target="clean" buildpathref="build-path" />
59 </target>
60
61 <target name="clean" depends="clean-all, load-ivy"
62 description="clean tutorial: delete repository, ivy cache, and all projects">
63 <delete dir="repository"/>
64 <ivy:cleancache />
65 </target>
66
67
6865 </project>
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 lib.dir = ${basedir}/lib
1919 build.dir = ${basedir}/build
2020 classes.dir = ${build.dir}/classes
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
18 <project name="common"
19 xmlns:ivy="antlib:org.apache.ivy.ant">
20 <!-- a sample common ant build file, used for ivy multi-project tutorial
21 feel free to copy and adapt it to your own needs
22 Note that the only targets specific to ivy are:
23 load-ivy
24 resolve
25 report
26 ivy-new-version
27 publish
28 publish-local
29
30 All other targets are usual ant based targets, which could have been written
31 in a build not depending at all on ivy:
32 resolve constructs a lib directory based upon ivy dependencies, and then the lib dir
33 is used as in any classical ant build
34 -->
35
36 <property file="${common.dir}/build.properties"/>
37
38 <property name="ivy.jar.dir" value="${user.home}/.ivy2/jars" />
39 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar" />
40
41 <!-- =================================
42 target: load-ivy
43 this target is not necessary if you put ivy.jar in your ant lib directory
44 if you already have ivy 2.0 in your ant lib, you can simply remove this
45 target
18 <project name="common" xmlns:ivy="antlib:org.apache.ivy.ant">
19 <!-- a sample common ant build file, used for ivy multi-project tutorial
20 feel free to copy and adapt it to your own needs
21 Note that the only targets specific to ivy are:
22 load-ivy
23 resolve
24 report
25 ivy-new-version
26 publish
27 publish-local
28
29 All other targets are usual ant based targets, which could have been written
30 in a build not depending at all on ivy:
31 resolve constructs a lib directory based upon ivy dependencies, and then the lib dir
32 is used as in any classical ant build
33 -->
34
35 <property file="${common.dir}/build.properties"/>
36
37 <property name="ivy.jar.dir" value="${user.home}/.ivy2/jars"/>
38 <property name="ivy.jar.file" value="${ivy.jar.dir}/ivy.jar"/>
39
40 <!-- =================================
41 target: load-ivy
42 this target is not necessary if you put ivy.jar in your ant lib directory
43 if you already have ivy 2.0 in your ant lib, you can simply remove this
44 target
4645 ================================= -->
4746 <target name="load-ivy">
48 <!-- try to load ivy here from home ivy dir, in case the user has not already dropped
49 it into ant's lib dir (note that the latter copy will always take precedence).
50 We will not fail as long as ivy home lib dir exists (it may be empty) and
51 ivy is in at least one of ant's lib dir or the ivy home lib dir. -->
52 <mkdir dir="${ivy.jar.dir}" />
53 <path id="ivy.lib.path">
54 <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
55 </path>
56 <taskdef resource="org/apache/ivy/ant/antlib.xml"
57 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
58 </target>
47 <!-- try to load ivy here from home ivy dir, in case the user has not already dropped
48 it into ant's lib dir (note that the latter copy will always take precedence).
49 We will not fail as long as ivy home lib dir exists (it may be empty) and
50 ivy is in at least one of ant's lib dir or the ivy home lib dir. -->
51 <mkdir dir="${ivy.jar.dir}"/>
52 <path id="ivy.lib.path">
53 <fileset dir="${ivy.jar.dir}" includes="*.jar"/>
54 </path>
55 <taskdef resource="org/apache/ivy/ant/antlib.xml"
56 uri="antlib:org.apache.ivy.ant" classpathref="ivy.lib.path"/>
57 </target>
5958
6059 <path id="lib.path.id">
61 <fileset dir="${lib.dir}" />
60 <fileset dir="${lib.dir}"/>
6261 </path>
6362 <path id="run.path.id">
64 <path refid="lib.path.id" />
65 <path location="${classes.dir}" />
63 <path refid="lib.path.id"/>
64 <path location="${classes.dir}"/>
6665 </path>
6766
68
69 <!-- setup ivy default configuration with some custom info -->
70 <property name="ivy.local.default.root" value="${repository.dir}/local"/>
71 <property name="ivy.shared.default.root" value="${repository.dir}/shared"/>
72
73 <!-- here is how we would have configured ivy if we had our own ivysettings file
74 <ivy:settings file="${common.dir}/ivysettings.xml" />
67 <!-- setup ivy default configuration with some custom info -->
68 <property name="ivy.local.default.root" value="${repository.dir}/local"/>
69 <property name="ivy.shared.default.root" value="${repository.dir}/shared"/>
70
71 <!-- here is how we would have configured ivy if we had our own ivysettings file
72 <ivy:settings file="${common.dir}/ivysettings.xml"/>
7573 -->
7674
77
78 <!-- =================================
79 target: resolve
75 <!-- =================================
76 target: resolve
8077 ================================= -->
8178 <target name="resolve" depends="clean-lib, load-ivy" description="--> resolve and retrieve dependencies with ivy">
8279 <mkdir dir="${lib.dir}"/> <!-- not usually necessary, ivy creates the directory IF there are dependencies -->
83
84 <!-- the call to resolve is not mandatory, retrieve makes an implicit call if we don't -->
85 <ivy:resolve file="${ivy.file}"/>
86 <ivy:retrieve pattern="${lib.dir}/[artifact].[ext]" />
87 </target>
88
89 <!-- =================================
90 target: report
80
81 <!-- the call to resolve is not mandatory, retrieve makes an implicit call if we don't -->
82 <ivy:resolve file="${ivy.file}"/>
83 <ivy:retrieve pattern="${lib.dir}/[artifact].[ext]"/>
84 </target>
85
86 <!-- =================================
87 target: report
9188 ================================= -->
9289 <target name="report" depends="resolve" description="--> generates a report of dependencies">
9390 <ivy:report todir="${build.dir}"/>
9491 </target>
95
96 <!-- =================================
97 target: compile
92
93 <!-- =================================
94 target: compile
9895 ================================= -->
9996 <target name="compile" depends="resolve" description="--> compile the project">
100 <mkdir dir="${classes.dir}" />
97 <mkdir dir="${classes.dir}"/>
10198 <javac srcdir="${src.dir}" destdir="${classes.dir}" classpathref="lib.path.id" debug="true" includeAntRuntime="false"/>
10299 </target>
103
104 <!-- =================================
105 target: run
100
101 <!-- =================================
102 target: run
106103 ================================= -->
107104 <target name="run" depends="version, compile" description="--> compile and run the project">
108105 <java classpathref="run.path.id" classname="${main.class.name}"/>
109106 </target>
110107
111 <target name="ivy-new-version" depends="load-ivy" unless="ivy.new.revision">
112 <!-- default module version prefix value -->
113 <property name="module.version.prefix" value="${module.version.target}-dev-b" />
114
115 <!-- asks to ivy an available version number -->
116 <ivy:info file="${ivy.file}" />
117 <ivy:buildnumber
118 organisation="${ivy.organisation}" module="${ivy.module}"
119 revision="${module.version.prefix}" defaultBuildNumber="1" revSep=""/>
120 </target>
121
122 <target name="local-version">
123 <tstamp>
124 <format property="now" pattern="yyyyMMddHHmmss"/>
125 </tstamp>
126 <property name="ivy.new.revision" value="${module.version.target}-local-${now}"/>
127 </target>
128
129 <target name="version" depends="ivy-new-version">
130 <!-- create version file in classpath for later inclusion in jar -->
131 <mkdir dir="${classes.dir}"/>
132 <echo message="version=${ivy.new.revision}" file="${classes.dir}/${ant.project.name}.properties" append="false" />
133
134 <!-- load generated version properties file -->
135 <property file="${classes.dir}/${ant.project.name}.properties" />
136 </target>
137
138 <!-- =================================
139 target: jar
140 ================================= -->
141 <target name="jar" depends="version, compile" description="--> make a jar file for this project">
142 <jar destfile="${jar.file}">
143 <fileset dir="${classes.dir}" />
144 <manifest>
145 <attribute name="Built-By" value="${user.name}"/>
146 <attribute name="Build-Version" value="${version}" />
147 </manifest>
148 </jar>
149 </target>
150
151 <!-- =================================
152 target: publish
153 ================================= -->
154 <target name="publish" depends="clean-build, jar" description="--> publish this project in the ivy repository">
155 <ivy:publish artifactspattern="${build.dir}/[artifact].[ext]"
156 resolver="shared"
157 pubrevision="${version}"
158 status="release"
159 />
160 <echo message="project ${ant.project.name} released with version ${version}" />
161 </target>
162
163 <!-- =================================
164 target: publish-local
165 ================================= -->
166 <target name="publish-local" depends="local-version, jar" description="--> publish this project in the local ivy repository">
167 <ivy:publish artifactspattern="${build.dir}/[artifact].[ext]"
168 resolver="local"
169 pubrevision="${version}"
170 pubdate="${now}"
171 status="integration"
172 forcedeliver="true"
173 />
174 <echo message="project ${ant.project.name} published locally with version ${version}" />
175 </target>
176
177 <!-- =================================
178 target: clean-local
179 ================================= -->
180 <target name="clean-local" depends="load-ivy"
181 description="--> cleans the local repository for the current module">
182 <ivy:info file="${ivy.file}" />
183 <delete dir="${ivy.local.default.root}/${ivy.organisation}/${ivy.module}"/>
184 </target>
185
186 <!-- =================================
187 target: clean-lib
188 ================================= -->
189 <target name="clean-lib" description="--> clean the project libraries directory (dependencies)">
190 <delete includeemptydirs="true" dir="${lib.dir}"/>
191 </target>
192
193 <!-- =================================
194 target: clean-build
195 ================================= -->
196 <target name="clean-build" description="--> clean the project built files">
197 <delete includeemptydirs="true" dir="${build.dir}"/>
198 </target>
199
200 <!-- =================================
201 target: clean
202 ================================= -->
203 <target name="clean" depends="clean-build, clean-lib" description="--> clean the project" />
108 <target name="ivy-new-version" depends="load-ivy" unless="ivy.new.revision">
109 <!-- default module version prefix value -->
110 <property name="module.version.prefix" value="${module.version.target}-dev-b"/>
111
112 <!-- asks to ivy an available version number -->
113 <ivy:info file="${ivy.file}"/>
114 <ivy:buildnumber
115 organisation="${ivy.organisation}" module="${ivy.module}"
116 revision="${module.version.prefix}" defaultBuildNumber="1" revSep=""/>
117 </target>
118
119 <target name="local-version">
120 <tstamp>
121 <format property="now" pattern="yyyyMMddHHmmss"/>
122 </tstamp>
123 <property name="ivy.new.revision" value="${module.version.target}-local-${now}"/>
124 </target>
125
126 <target name="version" depends="ivy-new-version">
127 <!-- create version file in classpath for later inclusion in jar -->
128 <mkdir dir="${classes.dir}"/>
129 <echo message="version=${ivy.new.revision}" file="${classes.dir}/${ant.project.name}.properties" append="false"/>
130
131 <!-- load generated version properties file -->
132 <property file="${classes.dir}/${ant.project.name}.properties"/>
133 </target>
134
135 <!-- =================================
136 target: jar
137 ================================= -->
138 <target name="jar" depends="version, compile" description="--> make a jar file for this project">
139 <jar destfile="${jar.file}">
140 <fileset dir="${classes.dir}"/>
141 <manifest>
142 <attribute name="Built-By" value="${user.name}"/>
143 <attribute name="Build-Version" value="${version}"/>
144 </manifest>
145 </jar>
146 </target>
147
148 <!-- =================================
149 target: publish
150 ================================= -->
151 <target name="publish" depends="clean-build, jar" description="--> publish this project in the ivy repository">
152 <ivy:publish artifactspattern="${build.dir}/[artifact].[ext]"
153 resolver="shared"
154 pubrevision="${version}"
155 status="release"/>
156 <echo message="project ${ant.project.name} released with version ${version}"/>
157 </target>
158
159 <!-- =================================
160 target: publish-local
161 ================================= -->
162 <target name="publish-local" depends="local-version, jar" description="--> publish this project in the local ivy repository">
163 <ivy:publish artifactspattern="${build.dir}/[artifact].[ext]"
164 resolver="local"
165 pubrevision="${version}"
166 pubdate="${now}"
167 status="integration"
168 forcedeliver="true"/>
169 <echo message="project ${ant.project.name} published locally with version ${version}"/>
170 </target>
171
172 <!-- =================================
173 target: clean-local
174 ================================= -->
175 <target name="clean-local" depends="load-ivy"
176 description="--> cleans the local repository for the current module">
177 <ivy:info file="${ivy.file}"/>
178 <delete dir="${ivy.local.default.root}/${ivy.organisation}/${ivy.module}"/>
179 </target>
180
181 <!-- =================================
182 target: clean-lib
183 ================================= -->
184 <target name="clean-lib" description="--> clean the project libraries directory (dependencies)">
185 <delete includeemptydirs="true" dir="${lib.dir}"/>
186 </target>
187
188 <!-- =================================
189 target: clean-build
190 ================================= -->
191 <target name="clean-build" description="--> clean the project built files">
192 <delete includeemptydirs="true" dir="${build.dir}"/>
193 </target>
194
195 <!-- =================================
196 target: clean
197 ================================= -->
198 <target name="clean" depends="clean-build,clean-lib" description="--> clean the project"/>
204199 </project>
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 projects.dir = ${basedir}/..
1919 wkspace.dir = ${projects.dir}/..
2020 common.dir = ${wkspace.dir}/common
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="console" default="compile">
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
2222 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
19 <info
2020 organisation="org.apache.ivy.example"
2121 module="console"
2222 status="integration"/>
2323 <dependencies>
24 <dependency name="version" rev="latest.integration" conf="default" />
25 <dependency name="list" rev="latest.integration" conf="default->standalone" />
26 <dependency name="find" rev="latest.integration" conf="default->standalone" />
27 <dependency name="sizewhere" rev="latest.integration" conf="default->standalone" />
24 <dependency name="version" rev="latest.integration" conf="default"/>
25 <dependency name="list" rev="latest.integration" conf="default->standalone"/>
26 <dependency name="find" rev="latest.integration" conf="default->standalone"/>
27 <dependency name="sizewhere" rev="latest.integration" conf="default->standalone"/>
2828 </dependencies>
2929 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424
2525
2626 public final class Main {
27 private static final Collection QUIT_COMMANDS =
28 Arrays.asList(new String[] {"quit", "q", "exit"});
29 private static final Collection HELP_COMMANDS =
30 Arrays.asList(new String[] {"help", "h", "?"});
27 private static final Collection<String> QUIT_COMMANDS =
28 Arrays.asList("quit", "q", "exit");
29 private static final Collection<String> HELP_COMMANDS =
30 Arrays.asList("help", "h", "?");
3131
3232 public static void main(String[] a) throws Exception {
3333 BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
4646 error(command);
4747 continue;
4848 }
49
49
5050 try {
5151 String[] args = new String[split.length - 1];
5252 System.arraycopy(split, 1, args, 0, args.length);
53 Class cl = Class.forName(split[0] + ".Main");
53 Class<?> cl = Class.forName(split[0] + ".Main");
5454 Method m = cl.getMethod("main", new Class[] {String[].class});
5555 m.invoke(null, new Object[] {args});
5656 } catch (Exception ex) {
5959 }
6060 }
6161 }
62
62
6363 private static void help() {
6464 System.out.println("available commands:");
6565 System.out.println("\tquit: quit the console");
7070 + "compute total size of files with given name in given dir");
7171 System.out.println("\thelp: displays this message");
7272 }
73
73
7474 private static void error(String command) {
7575 System.out.println("unknown command " + command);
7676 System.out.println("type ? for help");
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 projects.dir = ${basedir}/..
1919 wkspace.dir = ${projects.dir}/..
2020 common.dir = ${wkspace.dir}/common
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="find" default="compile">
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
2222 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
19 <info
2020 organisation="org.apache.ivy.example"
2121 module="find"
2222 status="integration"/>
2525 <conf name="standalone" extends="core"/>
2626 </configurations>
2727 <publications>
28 <artifact name="find" type="jar" conf="core" />
28 <artifact name="find" type="jar" conf="core"/>
2929 </publications>
3030 <dependencies>
31 <dependency name="version" rev="latest.integration" conf="core->default" />
32 <dependency name="list" rev="latest.integration" conf="core" />
33 <dependency org="commons-collections" name="commons-collections" rev="3.1" conf="core->default" />
34 <dependency org="commons-cli" name="commons-cli" rev="1.0" conf="standalone->default" />
31 <dependency name="version" rev="latest.integration" conf="core->default"/>
32 <dependency name="list" rev="latest.integration" conf="core"/>
33 <dependency org="org.apache.commons" name="commons-collections4" rev="4.1" conf="core->default"/>
34 <dependency org="commons-cli" name="commons-cli" rev="1.4" conf="standalone->default"/>
3535 </dependencies>
3636 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package find;
1818
19 import version.Version;
20 import list.ListFile;
21
2219 import java.util.Collection;
2320 import java.io.File;
2421
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.Predicate;
22 import org.apache.commons.collections4.CollectionUtils;
23 import org.apache.commons.collections4.Predicate;
24
25 import static list.ListFile.list;
26 import static version.Version.register;
2727
2828 public final class FindFile {
2929 static {
30 Version.register("find");
30 register("find");
3131 }
32
33 public static Collection find(File dir, String name) {
34 return find(ListFile.list(dir), name);
32
33 public static Collection<File> find(File dir, String name) {
34 return find(list(dir), name);
3535 }
36
37 private static Collection find(Collection files, final String name) {
38 return CollectionUtils.select(files, new Predicate() {
39 public boolean evaluate(Object o) {
40 return ((File) o).getName().indexOf(name) != -1;
36
37 private static Collection<File> find(Collection<File> files, final String name) {
38 return CollectionUtils.select(files, new Predicate<File>() {
39 public boolean evaluate(File file) {
40 return file.getName().contains(name);
4141 }
4242 });
4343 }
44
44
4545 private FindFile() {
4646 }
4747 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package find;
1818
19 import java.io.File;
20 import java.util.Collection;
21 import java.util.Iterator;
22
2319 import org.apache.commons.cli.CommandLine;
2420 import org.apache.commons.cli.CommandLineParser;
25 import org.apache.commons.cli.GnuParser;
21 import org.apache.commons.cli.DefaultParser;
2622 import org.apache.commons.cli.HelpFormatter;
2723 import org.apache.commons.cli.Option;
28 import org.apache.commons.cli.OptionBuilder;
2924 import org.apache.commons.cli.Options;
3025 import org.apache.commons.cli.ParseException;
3126
27 import java.io.File;
28 import java.util.Collection;
29
3230 public final class Main {
3331 private static Options getOptions() {
34 Option dir = OptionBuilder.withArgName("dir")
32 Option dir = Option.builder("d")
33 .longOpt("dir")
3534 .hasArg()
36 .withDescription("list files in given dir")
37 .create("dir");
38 Option name = OptionBuilder.withArgName("name")
35 .desc("list files in given dir")
36 .build();
37 Option name = Option.builder("n")
38 .longOpt("name")
3939 .hasArg()
40 .withDescription("list files with given name")
41 .create("name");
40 .desc("list files with given name")
41 .build();
4242 Options options = new Options();
4343
4444 options.addOption(dir);
4545 options.addOption(name);
46
46
4747 return options;
4848 }
49
49
5050 public static void main(String[] args) throws Exception {
5151 Options options = getOptions();
5252 try {
53
54 CommandLineParser parser = new GnuParser();
55
53
54 CommandLineParser parser = new DefaultParser();
55
5656 CommandLine line = parser.parse(options, args);
57 File dir = new File(line.getOptionValue("dir", "."));
58 String name = line.getOptionValue("name", "jar");
59 Collection files = FindFile.find(dir, name);
57 File dir = new File(line.getOptionValue("d", "."));
58 String name = line.getOptionValue("n", "jar");
59 Collection<File> files = FindFile.find(dir, name);
6060 System.out.println("listing files in " + dir + " containing " + name);
61 for (Iterator it = files.iterator(); it.hasNext();) {
62 System.out.println("\t" + it.next() + "\n");
61 for (File file : files) {
62 System.out.println("\t" + file + "\n");
6363 }
6464 } catch (ParseException exp) {
6565 // oops, something went wrong
6666 System.err.println("Parsing failed. Reason: " + exp.getMessage());
67
67
6868 HelpFormatter formatter = new HelpFormatter();
6969 formatter.printHelp("find", options);
70 }
70 }
7171 }
72
72
7373 private Main() {
7474 }
7575 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 projects.dir = ${basedir}/..
1919 wkspace.dir = ${projects.dir}/..
2020 common.dir = ${wkspace.dir}/common
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="list" default="compile">
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
2222 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
19 <info
2020 organisation="org.apache.ivy.example"
2121 module="list"
2222 status="integration"/>
2525 <conf name="standalone" extends="core"/>
2626 </configurations>
2727 <publications>
28 <artifact name="list" type="jar" conf="core" />
28 <artifact name="list" type="jar" conf="core"/>
2929 </publications>
3030 <dependencies>
31 <dependency name="version" rev="latest.integration" conf="core->default" />
32 <dependency org="commons-cli" name="commons-cli" rev="1.0" conf="standalone->default" />
31 <dependency name="version" rev="latest.integration" conf="core->default"/>
32 <dependency org="commons-cli" name="commons-cli" rev="1.4" conf="standalone->default"/>
3333 </dependencies>
3434 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package list;
1818
19 import version.Version;
2019 import java.util.Collection;
2120 import java.util.ArrayList;
2221 import java.io.File;
2322
23 import static version.Version.register;
24
2425 public final class ListFile {
2526 static {
26 Version.register("list");
27 register("list");
2728 }
28
29 public static Collection list(File dir) {
30 Collection files = new ArrayList();
31
29
30 public static Collection<File> list(File dir) {
31 Collection<File> files = new ArrayList<File>();
32
3233 return list(dir, files);
3334 }
34
35 private static Collection list(File file, Collection files) {
35
36 private static Collection<File> list(File file, Collection<File> files) {
3637 if (file.isDirectory()) {
37 File[] f = file.listFiles();
38 for (int i = 0; i < f.length; i++) {
39 list(f[i], files);
38 for (File f : file.listFiles()) {
39 list(f, files);
4040 }
4141 } else {
4242 files.add(file);
4343 }
4444 return files;
4545 }
46
46
4747 private ListFile() {
4848 }
4949 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package list;
1818
1919 import java.io.File;
20 import java.util.Collection;
21 import java.util.Iterator;
2220
2321 import org.apache.commons.cli.CommandLine;
2422 import org.apache.commons.cli.CommandLineParser;
25 import org.apache.commons.cli.GnuParser;
23 import org.apache.commons.cli.DefaultParser;
2624 import org.apache.commons.cli.HelpFormatter;
2725 import org.apache.commons.cli.Option;
28 import org.apache.commons.cli.OptionBuilder;
2926 import org.apache.commons.cli.Options;
3027 import org.apache.commons.cli.ParseException;
3128
3229 public final class Main {
3330 private static Options getOptions() {
34 Option dir = OptionBuilder.withArgName("dir")
31 Option dir = Option.builder("d")
32 .longOpt("dir")
3533 .hasArg()
36 .withDescription("list files in given dir")
37 .create("dir");
34 .desc("list files in given dir")
35 .build();
3836 Options options = new Options();
3937
4038 options.addOption(dir);
41
39
4240 return options;
4341 }
44
42
4543 public static void main(String[] args) throws Exception {
4644 Options options = getOptions();
4745 try {
48
49 CommandLineParser parser = new GnuParser();
46
47 CommandLineParser parser = new DefaultParser();
5048
5149 CommandLine line = parser.parse(options, args);
52 File dir = new File(line.getOptionValue("dir", "."));
53 Collection files = ListFile.list(dir);
54 System.out.println("listing files in " + dir);
55 for (Iterator it = files.iterator(); it.hasNext();) {
56 System.out.println("\t" + it.next() + "\n");
57 }
50 File dir = new File(line.getOptionValue("d", "."));
51 System.out.println("listing files in " + dir);
52 for (File file : ListFile.list(dir)) {
53 System.out.println("\t" + file + "\n");
54 }
5855 } catch (ParseException exp) {
5956 // oops, something went wrong
6057 System.err.println("Parsing failed. Reason: " + exp.getMessage());
61
58
6259 HelpFormatter formatter = new HelpFormatter();
6360 formatter.printHelp("list", options);
64 }
61 }
6562 }
66
63
6764 private Main() {
6865 }
69
66
7067 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 projects.dir = ${basedir}/..
1919 wkspace.dir = ${projects.dir}/..
2020 common.dir = ${wkspace.dir}/common
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="size" default="compile">
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
2222 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
19 <info
2020 organisation="org.apache.ivy.example"
2121 module="size"
2222 status="integration"/>
2323 <dependencies>
24 <dependency name="version" rev="latest.integration" conf="default" />
25 <dependency name="list" rev="latest.integration" conf="default->core" />
24 <dependency name="version" rev="latest.integration" conf="default"/>
25 <dependency name="list" rev="latest.integration" conf="default->core"/>
2626 </dependencies>
2727 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package size;
1818
19 import version.Version;
19 import java.io.File;
2020 import java.util.Collection;
21 import java.util.Iterator;
22 import java.io.File;
21
22 import static list.ListFile.list;
23 import static version.Version.register;
2324
2425 public final class FileSize {
2526 static {
26 Version.register("size");
27 register("size");
2728 }
2829
30 @SuppressWarnings("unused")
2931 public static long totalSize(File dir) {
30 return totalSize(list.ListFile.list(dir));
32 return totalSize(list(dir));
3133 }
32
33 public static long totalSize(Collection files) {
34
35 public static long totalSize(Collection<File> files) {
3436 long total = 0;
35 for (Iterator it = files.iterator(); it.hasNext();) {
36 File f = (File) it.next();
37 total += f.length();
37 for (File file : files) {
38 total += file.length();
3839 }
3940 return total;
40 }
41
41 }
42
4243 private FileSize() {
4344 }
4445 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 projects.dir = ${basedir}/..
1919 wkspace.dir = ${projects.dir}/..
2020 common.dir = ${wkspace.dir}/common
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="sizewhere" default="compile">
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
2222 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
19 <info
2020 organisation="org.apache.ivy.example"
2121 module="sizewhere"
2222 status="integration"/>
2525 <conf name="standalone" extends="core"/>
2626 </configurations>
2727 <publications>
28 <artifact name="sizewhere" type="jar" conf="core" />
28 <artifact name="sizewhere" type="jar" conf="core"/>
2929 </publications>
3030 <dependencies>
31 <dependency name="version" rev="latest.integration" conf="core->default" />
32 <dependency name="size" rev="latest.integration" conf="core->default" />
33 <dependency name="find" rev="latest.integration" conf="core" />
34 <dependency org="commons-cli" name="commons-cli" rev="1.0" conf="standalone->default" />
31 <dependency name="version" rev="latest.integration" conf="core->default"/>
32 <dependency name="size" rev="latest.integration" conf="core->default"/>
33 <dependency name="find" rev="latest.integration" conf="core"/>
34 <dependency org="commons-cli" name="commons-cli" rev="1.4" conf="standalone->default"/>
3535 </dependencies>
3636 </ivy-module>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package sizewhere;
1818
19 import java.io.File;
20
2119 import org.apache.commons.cli.CommandLine;
2220 import org.apache.commons.cli.CommandLineParser;
23 import org.apache.commons.cli.GnuParser;
21 import org.apache.commons.cli.DefaultParser;
2422 import org.apache.commons.cli.HelpFormatter;
2523 import org.apache.commons.cli.Option;
26 import org.apache.commons.cli.OptionBuilder;
2724 import org.apache.commons.cli.Options;
2825 import org.apache.commons.cli.ParseException;
2926
27 import java.io.File;
28
3029 public final class Main {
3130 private static Options getOptions() {
32 Option dir = OptionBuilder.withArgName("dir")
31 Option dir = Option.builder("d")
32 .longOpt("dir")
3333 .hasArg()
34 .withDescription("give total size of files in given dir")
35 .create("dir");
36 Option name = OptionBuilder.withArgName("name")
34 .desc("give total size of files in given dir")
35 .build();
36 Option name = Option.builder("n")
37 .longOpt("name")
3738 .hasArg()
38 .withDescription("give total size of files with given name")
39 .create("name");
39 .desc("give total size of files with given name")
40 .build();
4041 Options options = new Options();
4142
4243 options.addOption(dir);
4344 options.addOption(name);
44
45
4546 return options;
4647 }
47
48
4849 public static void main(String[] args) throws Exception {
4950 Options options = getOptions();
5051 try {
51
52 CommandLineParser parser = new GnuParser();
52 CommandLineParser parser = new DefaultParser();
5353
5454 CommandLine line = parser.parse(options, args);
55 File dir = new File(line.getOptionValue("dir", "."));
56 String name = line.getOptionValue("name", "jar");
57 System.out.println("total size of files in " + dir
55 File dir = new File(line.getOptionValue("d", "."));
56 String name = line.getOptionValue("n", "jar");
57 System.out.println("total size of files in " + dir
5858 + " containing " + name + ": " + SizeWhere.totalSize(dir, name));
5959 } catch (ParseException exp) {
60 // oops, something went wrong
61 System.err.println("Parsing failed. Reason: " + exp.getMessage());
62
60 // oops, something went wrong
61 System.err.println("Parsing failed. Reason: " + exp.getMessage());
62
6363 HelpFormatter formatter = new HelpFormatter();
6464 formatter.printHelp("sizewhere", options);
65 }
65 }
6666 }
67
67
6868 private Main() {
6969 }
7070 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package sizewhere;
1818
19 import version.Version;
2019 import size.FileSize;
21 import find.FindFile;
2220
2321 import java.io.File;
2422
23 import static find.FindFile.find;
24 import static version.Version.register;
25
2526 public final class SizeWhere {
2627 static {
27 Version.register("sizewhere");
28 register("sizewhere");
2829 }
29
30
3031 public static long totalSize(File dir, String name) {
31 return FileSize.totalSize(FindFile.find(dir, name));
32 return FileSize.totalSize(find(dir, name));
3233 }
33
34
3435 private SizeWhere() {
3536 }
3637 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 projects.dir = ${basedir}/..
1919 wkspace.dir = ${projects.dir}/..
2020 common.dir = ${wkspace.dir}/common
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <project name="version" default="compile">
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
19 <property file="build.properties"/>
20
21 <import file="${common.dir}/common.xml"/>
2222 </project>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivy-module version="1.0">
19 <info
19 <info
2020 organisation="org.apache.ivy.example"
2121 module="version"
2222 status="integration"/>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323
2424 public final class Version {
2525 static {
26 versions = new HashMap();
26 versions = new HashMap<>();
2727 register("version");
2828 }
29
30 private static Map versions;
31
29
30 private static Map<String, String> versions;
31
3232 public static void register(String module) {
3333 try {
3434 InputStream moduleVersion = Version.class.getResourceAsStream("/" + module
4444 ex.printStackTrace();
4545 }
4646 }
47
47
4848 private Version() {
4949 }
5050 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
1919 <resolvers>
3131 </modules>
3232 <caches useOrigin="true"/>
3333 </ivysettings>
34
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.text.ParseException;
2424 import java.text.SimpleDateFormat;
2525 import java.util.Collection;
26 import java.util.Iterator;
2726 import java.util.List;
2827 import java.util.Map;
2928 import java.util.Properties;
3736 import org.apache.ivy.core.event.EventManager;
3837 import org.apache.ivy.core.install.InstallEngine;
3938 import org.apache.ivy.core.install.InstallOptions;
39 import org.apache.ivy.core.module.descriptor.Artifact;
4040 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
4141 import org.apache.ivy.core.module.id.ModuleId;
4242 import org.apache.ivy.core.module.id.ModuleRevisionId;
4444 import org.apache.ivy.core.publish.PublishOptions;
4545 import org.apache.ivy.core.report.ResolveReport;
4646 import org.apache.ivy.core.repository.RepositoryManagementEngine;
47 import org.apache.ivy.core.resolve.IvyNode;
4748 import org.apache.ivy.core.resolve.ResolveData;
4849 import org.apache.ivy.core.resolve.ResolveEngine;
4950 import org.apache.ivy.core.resolve.ResolveOptions;
7172 import org.apache.ivy.util.MessageLoggerEngine;
7273
7374 /**
74 * <a href="http://ant.apache.org/ivy/">Ivy</a> is a free java based dependency manager.
75 * <a href="https://ant.apache.org/ivy/">Ivy</a> is a free java based dependency manager.
7576 * <p>
7677 * This class is the main class of Ivy, which acts as a Facade to all services offered by Ivy:
78 * </p>
7779 * <ul>
7880 * <li>resolve dependencies</li>
7981 * <li>retrieve artifacts to a local location</li>
8183 * <li>repository search and listing</li>
8284 * </ul>
8385 * Here is one typical usage:
84 *
8586 * <pre>
8687 * Ivy ivy = Ivy.newInstance();
8788 * ivy.configure(new URL(&quot;ivysettings.xml&quot;));
8889 * ivy.resolve(new URL(&quot;ivy.xml&quot;));
8990 * </pre>
90 *
91 * </p>
9291 * <h2>Using Ivy engines directly</h2>
9392 * <p>
9493 * If the methods offered by the {@link Ivy} class are not flexible enough and you want to use Ivy
9594 * engines directly, you need to call the methods within a single {@link IvyContext} associated to
96 * the {@link Ivy} instance you use.<br/>
95 * the {@link Ivy} instance you use.
96 * </p>
97 * <p>
9798 * To do so, it is recommended to use the {@link #execute(org.apache.ivy.Ivy.IvyCallback)} method
9899 * like this:
99 *
100 * </p>
100101 * <pre>
101102 * Ivy ivy = Ivy.newInstance();
102103 * ivy.execute(new IvyCallback() {
109110 * }
110111 * });
111112 * </pre>
112 *
113 * </p>
114113 */
115114 public class Ivy {
116115 /**
117116 * Callback used to execute a set of Ivy related methods within an {@link IvyContext}.
118 *
117 *
119118 * @see Ivy#execute(org.apache.ivy.Ivy.IvyCallback)
120119 */
121 public static interface IvyCallback {
120 public interface IvyCallback {
122121 /**
123122 * Executes Ivy related job within an {@link IvyContext}
124 *
123 *
125124 * @param ivy
126125 * the {@link Ivy} instance to which this callback is related
127126 * @param context
128127 * the {@link IvyContext} in which this callback is executed
129128 * @return the result of this job, <code>null</code> if there is no result
130129 */
131 public Object doInIvyContext(Ivy ivy, IvyContext context);
130 Object doInIvyContext(Ivy ivy, IvyContext context);
132131 }
133132
134133 private static final int KILO = 1024;
169168
170169 /**
171170 * Returns the current version of Ivy, as displayed on the console when Ivy is initialized.
172 *
171 *
173172 * @return the current version of Ivy
174173 */
175174 public static String getIvyVersion() {
178177
179178 /**
180179 * Returns the date at which this version of Ivy has been built.
181 * <p>
182 * May be empty if unknown.
183 *
180 * <p>May be empty if unknown.</p>
181 *
184182 * @return the date at which this version of Ivy has been built
185183 */
186184 public static String getIvyDate() {
189187
190188 /**
191189 * Returns the URL at which Ivy web site can be found.
192 *
190 *
193191 * @return the URL at which Ivy web site can be found
194192 */
195193 public static String getIvyHomeURL() {
196 return "http://ant.apache.org/ivy/";
194 return "https://ant.apache.org/ivy/";
197195 }
198196
199197 public static Ivy newInstance() {
216214
217215 /**
218216 * True if this instance of Ivy has already been bound to its dependencies, false otherwise.
219 *
220 * @see bind()
217 *
218 * @see #bind()
221219 */
222220 private boolean bound;
223221
342340 * <p>
343341 * Alternatively you can use the {@link #pushContext()} and {@link #popContext()} methods, but
344342 * this is not recommended:
345 *
343 * </p>
346344 * <pre>
347345 * Object result = null;
348346 * pushContext();
353351 * }
354352 * doSomethingWithResult(result);
355353 * </pre>
356 *
357 * </p>
358 *
359 * @param callback
360 * @return
354 *
355 * @param callback IvyCallback
356 * @return Object
361357 */
362358 public Object execute(IvyCallback callback) {
363359 pushContext();
444440
445441 /**
446442 * Configures Ivy with 1.4 compatible default settings
443 *
444 * @throws ParseException if something goes wrong
445 * @throws IOException if something goes wrong
447446 */
448447 public void configureDefault14() throws ParseException, IOException {
449448 pushContext();
543542 // RETRIEVE
544543 // ///////////////////////////////////////////////////////////////////////
545544
545 @Deprecated
546546 public int retrieve(ModuleRevisionId mrid, String destFilePattern, RetrieveOptions options)
547547 throws IOException {
548548 pushContext();
591591 /**
592592 * Example of use: deliver(mrid, "1.5", "target/ivy/ivy-[revision].xml",
593593 * DeliverOptions.newInstance(settings).setStatus("release").setValidate(false));
594 *
595 * @param mrid
596 * @param revision
597 * @param destIvyPattern
598 * @param options
599 * @throws IOException
600 * @throws ParseException
594 *
595 * @param mrid ModuleRevisionId
596 * @param revision String
597 * @param destIvyPattern String
598 * @param options DeliverOptions
599 * @throws IOException if something goes wrong
600 * @throws ParseException if something goes wrong
601601 */
602602 public void deliver(ModuleRevisionId mrid, String revision, String destIvyPattern,
603603 DeliverOptions options) throws IOException, ParseException {
613613 // PUBLISH
614614 // ///////////////////////////////////////////////////////////////////////
615615
616 public Collection publish(ModuleRevisionId mrid, Collection srcArtifactPattern,
617 String resolverName, PublishOptions options) throws IOException {
616 public Collection<Artifact> publish(ModuleRevisionId mrid,
617 Collection<String> srcArtifactPattern, String resolverName, PublishOptions options)
618 throws IOException {
618619 pushContext();
619620 try {
620621 return publishEngine.publish(mrid, srcArtifactPattern, resolverName, options);
629630
630631 /**
631632 * Sorts the collection of IvyNode from the less dependent to the more dependent
632 */
633 public List sortNodes(Collection nodes, SortOptions options) {
633 *
634 * @param nodes Collection&lt;IvyNode&gt;
635 * @param options SortOptions
636 * @return List&lt;IvyNode&gt;
637 */
638 public List<IvyNode> sortNodes(Collection<IvyNode> nodes, SortOptions options) {
634639 pushContext();
635640 try {
636641 return getSortEngine().sortNodes(nodes, options);
643648 * Sorts the given ModuleDescriptors from the less dependent to the more dependent. This sort
644649 * ensures that a ModuleDescriptor is always found in the list before all ModuleDescriptors
645650 * depending directly on it.
646 *
651 *
647652 * @param moduleDescriptors
648653 * a Collection of ModuleDescriptor to sort
649654 * @param options
653658 * if a circular dependency exists and circular dependency strategy decide to throw
654659 * an exception
655660 */
656 public List sortModuleDescriptors(Collection moduleDescriptors, SortOptions options) {
661 public List<ModuleDescriptor> sortModuleDescriptors(
662 Collection<ModuleDescriptor> moduleDescriptors, SortOptions options) {
657663 pushContext();
658664 try {
659665 return getSortEngine().sortModuleDescriptors(moduleDescriptors, options);
749755 }
750756 }
751757
752 public String[] listTokenValues(String token, Map otherTokenValues) {
758 public String[] listTokenValues(String token, Map<String, Object> otherTokenValues) {
753759 pushContext();
754760 try {
755761 return searchEngine.listTokenValues(token, otherTokenValues);
774780 /**
775781 * Interrupts the current running operation in the given operating thread, no later than
776782 * interruptTimeout milliseconds after the call
777 */
783 *
784 * @param operatingThread Thread
785 */
786 @SuppressWarnings("deprecation")
778787 public void interrupt(Thread operatingThread) {
779788 if (operatingThread != null && operatingThread.isAlive()) {
780789 if (operatingThread == Thread.currentThread()) {
832841 }
833842
834843 private void postConfigure() {
835 Collection triggers = settings.getTriggers();
836 for (Iterator iter = triggers.iterator(); iter.hasNext();) {
837 Trigger trigger = (Trigger) iter.next();
844 List<Trigger> triggers = settings.getTriggers();
845 for (Trigger trigger : triggers) {
838846 eventManager.addIvyListener(trigger, trigger.getEventFilter());
839847 }
840848
841 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
842 DependencyResolver resolver = (DependencyResolver) iter.next();
849 for (DependencyResolver resolver : settings.getResolvers()) {
843850 if (resolver instanceof BasicResolver) {
844851 ((BasicResolver) resolver).setEventManager(eventManager);
845852 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 import java.util.Date;
2626 import java.util.List;
2727 import java.util.Map;
28 import java.util.Set;
2829
2930 import org.apache.ivy.core.deliver.DeliverOptions;
3031 import org.apache.ivy.core.deliver.PublishingDependencyRevisionResolver;
5253 import org.apache.ivy.util.filter.Filter;
5354 import org.apache.ivy.util.filter.FilterHelper;
5455
56 import static org.apache.ivy.util.StringUtils.splitToArray;
57
5558 /**
5659 * This class can be used for easy migration from Ivy 1.4 API.
5760 * <p>
6063 * instance of this class.
6164 * <p>
6265 * For instance, where you were doing:
63 *
66 *
6467 * <pre>
6568 * Ivy ivy = new Ivy();
6669 * </pre>
67 *
70 *
6871 * do instead:
69 *
72 *
7073 * <pre>
7174 * Ivy14 ivy = new Ivy14();
7275 * </pre>
73 *
76 *
7477 * And that should be enough in most cases!
7578 */
7679 public class Ivy14 {
116119 deliver(mrid, revision, cache, destIvyPattern, status, pubdate, pdrResolver, validate, true);
117120 }
118121
119 public Map determineArtifactsToCopy(ModuleId moduleId, String[] confs, File cache,
120 String destFilePattern, String destIvyPattern, Filter artifactFilter)
121 throws ParseException, IOException {
122 public Map<ArtifactDownloadReport, Set<String>> determineArtifactsToCopy(ModuleId moduleId,
123 String[] confs, File cache, String destFilePattern, String destIvyPattern,
124 Filter<Artifact> artifactFilter) throws ParseException, IOException {
122125 return ivy.getRetrieveEngine().determineArtifactsToCopy(
123 new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()),
124 destFilePattern,
126 new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()), destFilePattern,
125127 new RetrieveOptions().setConfs(confs).setDestIvyPattern(destIvyPattern)
126128 .setArtifactFilter(artifactFilter));
127129 }
128130
129 public Map determineArtifactsToCopy(ModuleId moduleId, String[] confs, File cache,
130 String destFilePattern, String destIvyPattern) throws ParseException, IOException {
131 public Map<ArtifactDownloadReport, Set<String>> determineArtifactsToCopy(ModuleId moduleId,
132 String[] confs, File cache, String destFilePattern, String destIvyPattern)
133 throws ParseException, IOException {
131134 return ivy.getRetrieveEngine().determineArtifactsToCopy(
132135 new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()), destFilePattern,
133136 new RetrieveOptions().setConfs(confs).setDestIvyPattern(destIvyPattern));
146149
147150 public IvyNode[] getDependencies(ModuleDescriptor md, String[] confs, File cache, Date date,
148151 ResolveReport report, boolean validate, boolean transitive) {
149 return ivy.getResolveEngine().getDependencies(
150 md,
151 newResolveOptions(confs, null, cache, date, validate, false, transitive, false, true,
152 true, FilterHelper.NO_FILTER), report);
152 return ivy.getResolveEngine().getDependencies(md, newResolveOptions(confs, null, cache,
153 date, validate, false, transitive, false, true, true, FilterHelper.NO_FILTER), report);
153154 }
154155
155156 public IvyNode[] getDependencies(ModuleDescriptor md, String[] confs, File cache, Date date,
156157 ResolveReport report, boolean validate) {
157 return ivy.getResolveEngine().getDependencies(
158 md,
159 newResolveOptions(confs, null, cache, date, validate, false, true, false, true, true,
160 FilterHelper.NO_FILTER), report);
158 return ivy.getResolveEngine().getDependencies(md, newResolveOptions(confs, null, cache,
159 date, validate, false, true, false, true, true, FilterHelper.NO_FILTER), report);
161160 }
162161
163162 public IvyNode[] getDependencies(URL ivySource, String[] confs, File cache, Date date,
164163 boolean validate) throws ParseException, IOException {
165 return ivy.getResolveEngine().getDependencies(
166 ivySource,
167 newResolveOptions(confs, null, cache, date, validate, false, true, false, true, true,
168 FilterHelper.NO_FILTER));
164 return ivy.getResolveEngine().getDependencies(ivySource, newResolveOptions(confs, null,
165 cache, date, validate, false, true, false, true, true, FilterHelper.NO_FILTER));
169166 }
170167
171168 public String getVariable(String name) {
173170 }
174171
175172 public ResolveReport install(ModuleRevisionId mrid, String from, String to, boolean transitive,
176 boolean validate, boolean overwrite, Filter artifactFilter, File cache,
173 boolean validate, boolean overwrite, Filter<Artifact> artifactFilter, File cache,
177174 String matcherName) throws IOException {
178 return ivy.install(mrid, from, to, new InstallOptions().setTransitive(transitive)
179 .setValidate(validate).setOverwrite(overwrite).setArtifactFilter(artifactFilter)
180 .setMatcherName(matcherName));
175 return ivy.install(mrid, from, to,
176 new InstallOptions().setTransitive(transitive).setValidate(validate)
177 .setOverwrite(overwrite).setArtifactFilter(artifactFilter)
178 .setMatcherName(matcherName));
181179 }
182180
183181 public void interrupt() {
224222 return ivy.listRevisions(org, module);
225223 }
226224
227 public String[] listTokenValues(String token, Map otherTokenValues) {
225 public String[] listTokenValues(String token, Map<String, Object> otherTokenValues) {
228226 return ivy.listTokenValues(token, otherTokenValues);
229227 }
230228
231 public Collection publish(ModuleDescriptor md, DependencyResolver resolver,
232 Collection srcArtifactPattern, String srcIvyPattern, Artifact[] extraArtifacts,
229 public Collection<Artifact> publish(ModuleDescriptor md, DependencyResolver resolver,
230 Collection<String> srcArtifactPattern, String srcIvyPattern, Artifact[] extraArtifacts,
233231 boolean overwrite, String conf) throws IOException {
234 return ivy.getPublishEngine().publish(
235 md,
236 srcArtifactPattern,
237 resolver,
232 return ivy.getPublishEngine().publish(md, srcArtifactPattern, resolver,
238233 new PublishOptions().setSrcIvyPattern(srcIvyPattern).setExtraArtifacts(extraArtifacts)
239 .setOverwrite(overwrite).setConfs(splitConfs(conf)));
240 }
241
242 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache,
243 Collection srcArtifactPattern, String resolverName, String srcIvyPattern,
234 .setOverwrite(overwrite).setConfs(splitToArray(conf)));
235 }
236
237 public Collection<Artifact> publish(ModuleRevisionId mrid, String pubrevision, File cache,
238 Collection<String> srcArtifactPattern, String resolverName, String srcIvyPattern,
244239 String status, Date pubdate, Artifact[] extraArtifacts, boolean validate,
245240 boolean overwrite, boolean update, String conf) throws IOException {
246 return ivy.publish(
247 mrid,
248 srcArtifactPattern,
249 resolverName,
241 return ivy.publish(mrid, srcArtifactPattern, resolverName,
250242 new PublishOptions().setStatus(status).setPubdate(pubdate).setPubrevision(pubrevision)
251243 .setSrcIvyPattern(srcIvyPattern).setExtraArtifacts(extraArtifacts)
252244 .setUpdate(update).setValidate(validate).setOverwrite(overwrite)
253 .setConfs(splitConfs(conf)));
254 }
255
256 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache,
245 .setConfs(splitToArray(conf)));
246 }
247
248 public Collection<Artifact> publish(ModuleRevisionId mrid, String pubrevision, File cache,
257249 String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate,
258250 boolean overwrite) throws IOException {
259251 return ivy.publish(mrid, Collections.singleton(srcArtifactPattern), resolverName,
261253 .setValidate(validate).setOverwrite(overwrite));
262254 }
263255
264 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache,
256 public Collection<Artifact> publish(ModuleRevisionId mrid, String pubrevision, File cache,
265257 String srcArtifactPattern, String resolverName, String srcIvyPattern, boolean validate)
266258 throws IOException {
267259 return ivy.publish(mrid, Collections.singleton(srcArtifactPattern), resolverName,
269261 .setValidate(validate));
270262 }
271263
272 public Collection publish(ModuleRevisionId mrid, String pubrevision, File cache,
264 public Collection<Artifact> publish(ModuleRevisionId mrid, String pubrevision, File cache,
273265 String srcArtifactPattern, String resolverName, String srcIvyPattern, String status,
274266 Date pubdate, Artifact[] extraArtifacts, boolean validate, boolean overwrite,
275267 boolean update, String conf) throws IOException {
276 return ivy.publish(
277 mrid,
278 Collections.singleton(srcArtifactPattern),
279 resolverName,
268 return ivy.publish(mrid, Collections.singleton(srcArtifactPattern), resolverName,
280269 new PublishOptions().setStatus(status).setPubdate(pubdate).setPubrevision(pubrevision)
281270 .setSrcIvyPattern(srcIvyPattern).setExtraArtifacts(extraArtifacts)
282271 .setUpdate(update).setValidate(validate).setOverwrite(overwrite)
283 .setConfs(splitConfs(conf)));
272 .setConfs(splitToArray(conf)));
284273 }
285274
286275 public ResolveReport resolve(File ivySource) throws ParseException, IOException {
289278
290279 public ResolveReport resolve(ModuleDescriptor md, String[] confs, File cache, Date date,
291280 boolean validate, boolean useCacheOnly, boolean transitive, boolean useOrigin,
292 boolean download, boolean outputReport, Filter artifactFilter) throws ParseException,
293 IOException {
294 return ivy.resolve(
295 md,
296 newResolveOptions(confs, null, cache, date, validate, useCacheOnly, transitive,
297 useOrigin, download, outputReport, artifactFilter));
298 }
299
300 private ResolveOptions newResolveOptions(String[] confs, String revision, File cache,
301 Date date, boolean validate, boolean useCacheOnly, boolean transitive,
302 boolean useOrigin, boolean download, boolean outputReport, Filter artifactFilter) {
281 boolean download, boolean outputReport, Filter<Artifact> artifactFilter)
282 throws ParseException, IOException {
283 return ivy.resolve(md, newResolveOptions(confs, null, cache, date, validate, useCacheOnly,
284 transitive, useOrigin, download, outputReport, artifactFilter));
285 }
286
287 private ResolveOptions newResolveOptions(String[] confs, String revision, File cache, Date date,
288 boolean validate, boolean useCacheOnly, boolean transitive, boolean useOrigin,
289 boolean download, boolean outputReport, Filter<Artifact> artifactFilter) {
303290 if (useOrigin) {
304291 ivy.getSettings().useDeprecatedUseOrigin();
305292 }
310297
311298 public ResolveReport resolve(ModuleDescriptor md, String[] confs, File cache, Date date,
312299 boolean validate, boolean useCacheOnly, boolean transitive, boolean download,
313 boolean outputReport, Filter artifactFilter) throws ParseException, IOException {
314 return ivy.resolve(
315 md,
316 newResolveOptions(confs, null, cache, date, validate, useCacheOnly, transitive, false,
317 download, outputReport, artifactFilter));
300 boolean outputReport, Filter<Artifact> artifactFilter)
301 throws ParseException, IOException {
302 return ivy.resolve(md, newResolveOptions(confs, null, cache, date, validate, useCacheOnly,
303 transitive, false, download, outputReport, artifactFilter));
318304 }
319305
320306 public ResolveReport resolve(ModuleDescriptor md, String[] confs, File cache, Date date,
321 boolean validate, boolean useCacheOnly, boolean transitive, Filter artifactFilter)
322 throws ParseException, IOException {
323 return ivy.resolve(
324 md,
325 newResolveOptions(confs, null, cache, date, validate, useCacheOnly, transitive, false,
326 true, true, artifactFilter));
307 boolean validate, boolean useCacheOnly, boolean transitive,
308 Filter<Artifact> artifactFilter) throws ParseException, IOException {
309 return ivy.resolve(md, newResolveOptions(confs, null, cache, date, validate, useCacheOnly,
310 transitive, false, true, true, artifactFilter));
327311 }
328312
329313 public ResolveReport resolve(ModuleDescriptor md, String[] confs, File cache, Date date,
330 boolean validate, boolean useCacheOnly, Filter artifactFilter) throws ParseException,
331 IOException {
332 return ivy.resolve(
333 md,
334 newResolveOptions(confs, null, cache, date, validate, useCacheOnly, true, false, true,
335 true, artifactFilter));
314 boolean validate, boolean useCacheOnly, Filter<Artifact> artifactFilter)
315 throws ParseException, IOException {
316 return ivy.resolve(md, newResolveOptions(confs, null, cache, date, validate, useCacheOnly,
317 true, false, true, true, artifactFilter));
336318 }
337319
338320 public ResolveReport resolve(ModuleRevisionId mrid, String[] confs, boolean transitive,
339321 boolean changing, File cache, Date date, boolean validate, boolean useCacheOnly,
340 boolean useOrigin, Filter artifactFilter) throws ParseException, IOException {
341 return ivy.resolve(
342 mrid,
343 newResolveOptions(confs, null, cache, date, validate, useCacheOnly, transitive,
344 useOrigin, true, true, artifactFilter), changing);
322 boolean useOrigin, Filter<Artifact> artifactFilter) throws ParseException, IOException {
323 return ivy.resolve(mrid, newResolveOptions(confs, null, cache, date, validate, useCacheOnly,
324 transitive, useOrigin, true, true, artifactFilter), changing);
345325 }
346326
347327 public ResolveReport resolve(ModuleRevisionId mrid, String[] confs, boolean transitive,
348328 boolean changing, File cache, Date date, boolean validate, boolean useCacheOnly,
349 Filter artifactFilter) throws ParseException, IOException {
350 return ivy.resolve(
351 mrid,
352 newResolveOptions(confs, null, cache, date, validate, useCacheOnly, transitive, false,
353 true, true, artifactFilter), changing);
354 }
355
356 public ResolveReport resolve(ModuleRevisionId mrid, String[] confs) throws ParseException,
357 IOException {
358 return ivy.resolve(
359 mrid,
360 newResolveOptions(confs, null, ivy.getSettings().getDefaultCache(), null, true, false,
361 true, false, true, true, FilterHelper.NO_FILTER), false);
329 Filter<Artifact> artifactFilter) throws ParseException, IOException {
330 return ivy.resolve(mrid, newResolveOptions(confs, null, cache, date, validate, useCacheOnly,
331 transitive, false, true, true, artifactFilter), changing);
332 }
333
334 public ResolveReport resolve(ModuleRevisionId mrid, String[] confs)
335 throws ParseException, IOException {
336 return ivy.resolve(mrid, newResolveOptions(confs, null, ivy.getSettings().getDefaultCache(),
337 null, true, false, true, false, true, true, FilterHelper.NO_FILTER), false);
362338 }
363339
364340 public ResolveReport resolve(URL ivySource, String revision, String[] confs, File cache,
365341 Date date, boolean validate, boolean useCacheOnly, boolean transitive,
366 boolean useOrigin, Filter artifactFilter) throws ParseException, IOException {
367 return ivy.resolve(
368 ivySource,
369 newResolveOptions(confs, revision, cache, date, validate, useCacheOnly, transitive,
370 useOrigin, true, true, artifactFilter));
342 boolean useOrigin, Filter<Artifact> artifactFilter) throws ParseException, IOException {
343 return ivy.resolve(ivySource, newResolveOptions(confs, revision, cache, date, validate,
344 useCacheOnly, transitive, useOrigin, true, true, artifactFilter));
371345 }
372346
373347 public ResolveReport resolve(URL ivySource, String revision, String[] confs, File cache,
374348 Date date, boolean validate, boolean useCacheOnly, boolean transitive,
375 Filter artifactFilter) throws ParseException, IOException {
376 return ivy.resolve(
377 ivySource,
378 newResolveOptions(confs, revision, cache, date, validate, useCacheOnly, transitive,
379 false, true, true, artifactFilter));
349 Filter<Artifact> artifactFilter) throws ParseException, IOException {
350 return ivy.resolve(ivySource, newResolveOptions(confs, revision, cache, date, validate,
351 useCacheOnly, transitive, false, true, true, artifactFilter));
380352 }
381353
382354 public ResolveReport resolve(URL ivySource, String revision, String[] confs, File cache,
383 Date date, boolean validate, boolean useCacheOnly, Filter artifactFilter)
384 throws ParseException, IOException {
385 return ivy.resolve(
386 ivySource,
387 newResolveOptions(confs, revision, cache, date, validate, useCacheOnly, true, false,
388 true, true, artifactFilter));
355 Date date, boolean validate, boolean useCacheOnly, Filter<Artifact> artifactFilter)
356 throws ParseException, IOException {
357 return ivy.resolve(ivySource, newResolveOptions(confs, revision, cache, date, validate,
358 useCacheOnly, true, false, true, true, artifactFilter));
389359 }
390360
391361 public ResolveReport resolve(URL ivySource, String revision, String[] confs, File cache,
392362 Date date, boolean validate, boolean useCacheOnly) throws ParseException, IOException {
393 return ivy.resolve(
394 ivySource,
395 newResolveOptions(confs, revision, cache, date, validate, useCacheOnly, true, false,
396 true, true, FilterHelper.NO_FILTER));
363 return ivy.resolve(ivySource, newResolveOptions(confs, revision, cache, date, validate,
364 useCacheOnly, true, false, true, true, FilterHelper.NO_FILTER));
397365 }
398366
399367 public ResolveReport resolve(URL ivySource, String revision, String[] confs, File cache,
400368 Date date, boolean validate) throws ParseException, IOException {
401 return ivy.resolve(
402 ivySource,
403 newResolveOptions(confs, revision, cache, date, validate, false, true, false, true,
404 true, FilterHelper.NO_FILTER));
369 return ivy.resolve(ivySource, newResolveOptions(confs, revision, cache, date, validate,
370 false, true, false, true, true, FilterHelper.NO_FILTER));
405371 }
406372
407373 public ResolveReport resolve(URL ivySource) throws ParseException, IOException {
409375 }
410376
411377 public int retrieve(ModuleId moduleId, String[] confs, File cache, String destFilePattern,
412 String destIvyPattern, Filter artifactFilter, boolean sync, boolean useOrigin,
378 String destIvyPattern, Filter<Artifact> artifactFilter, boolean sync, boolean useOrigin,
413379 boolean makeSymlinks) {
414380 try {
415381 return ivy.retrieve(new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()),
416 destFilePattern,
417 new RetrieveOptions().setConfs(confs).setDestIvyPattern(destIvyPattern)
382 new RetrieveOptions().setConfs(confs).setDestArtifactPattern(destFilePattern)
383 .setDestIvyPattern(destIvyPattern)
418384 .setArtifactFilter(artifactFilter).setSync(sync).setUseOrigin(useOrigin)
419 .setMakeSymlinks(makeSymlinks));
385 .setMakeSymlinks(makeSymlinks)).getNbrArtifactsCopied();
420386 } catch (IOException e) {
421387 throw new RuntimeException(e);
422388 }
423389 }
424390
425391 public int retrieve(ModuleId moduleId, String[] confs, File cache, String destFilePattern,
426 String destIvyPattern, Filter artifactFilter, boolean sync, boolean useOrigin) {
392 String destIvyPattern, Filter<Artifact> artifactFilter, boolean sync,
393 boolean useOrigin) {
427394 try {
428395 return ivy.retrieve(new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()),
429 destFilePattern,
430 new RetrieveOptions().setConfs(confs).setDestIvyPattern(destIvyPattern)
431 .setArtifactFilter(artifactFilter).setSync(sync).setUseOrigin(useOrigin));
396 new RetrieveOptions().setConfs(confs).setDestArtifactPattern(destFilePattern)
397 .setDestIvyPattern(destIvyPattern)
398 .setArtifactFilter(artifactFilter).setSync(sync)
399 .setUseOrigin(useOrigin)).getNbrArtifactsCopied();
432400 } catch (IOException e) {
433401 throw new RuntimeException(e);
434402 }
435403 }
436404
437405 public int retrieve(ModuleId moduleId, String[] confs, File cache, String destFilePattern,
438 String destIvyPattern, Filter artifactFilter) {
406 String destIvyPattern, Filter<Artifact> artifactFilter) {
439407 try {
440408 return ivy.retrieve(new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()),
441 destFilePattern,
442 new RetrieveOptions().setConfs(confs).setDestIvyPattern(destIvyPattern)
443 .setArtifactFilter(artifactFilter));
409 new RetrieveOptions().setConfs(confs).setDestArtifactPattern(destFilePattern)
410 .setDestIvyPattern(destIvyPattern)
411 .setArtifactFilter(artifactFilter)).getNbrArtifactsCopied();
444412 } catch (IOException e) {
445413 throw new RuntimeException(e);
446414 }
450418 String destIvyPattern) {
451419 try {
452420 return ivy.retrieve(new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()),
453 destFilePattern,
454 new RetrieveOptions().setConfs(confs).setDestIvyPattern(destIvyPattern));
421 new RetrieveOptions().setConfs(confs).setDestArtifactPattern(destFilePattern)
422 .setDestIvyPattern(destIvyPattern)).getNbrArtifactsCopied();
455423 } catch (IOException e) {
456424 throw new RuntimeException(e);
457425 }
460428 public int retrieve(ModuleId moduleId, String[] confs, File cache, String destFilePattern) {
461429 try {
462430 return ivy.retrieve(new ModuleRevisionId(moduleId, Ivy.getWorkingRevision()),
463 destFilePattern, new RetrieveOptions().setConfs(confs));
431 new RetrieveOptions().setConfs(confs)
432 .setDestArtifactPattern(destFilePattern)).getNbrArtifactsCopied();
464433 } catch (IOException e) {
465434 throw new RuntimeException(e);
466435 }
470439 ivy.setVariable(varName, value);
471440 }
472441
473 public List sortModuleDescriptors(Collection moduleDescriptors) {
474 return ivy
475 .sortModuleDescriptors(moduleDescriptors, new SortOptions()
476 .setNonMatchingVersionReporter(new SilentNonMatchingVersionReporter()));
477 }
478
479 public List sortNodes(Collection nodes) {
480 return ivy
481 .sortNodes(nodes, new SortOptions()
482 .setNonMatchingVersionReporter(new SilentNonMatchingVersionReporter()));
442 public List<ModuleDescriptor> sortModuleDescriptors(
443 Collection<ModuleDescriptor> moduleDescriptors) {
444 return ivy.sortModuleDescriptors(moduleDescriptors, new SortOptions()
445 .setNonMatchingVersionReporter(new SilentNonMatchingVersionReporter()));
446 }
447
448 public List<IvyNode> sortNodes(Collection<IvyNode> nodes) {
449 return ivy.sortNodes(nodes, new SortOptions()
450 .setNonMatchingVersionReporter(new SilentNonMatchingVersionReporter()));
483451 }
484452
485453 public String substitute(String str) {
486454 return ivy.substitute(str);
487455 }
488456
489 private String[] splitConfs(String conf) {
490 if (conf == null || "".equals(conf)) {
491 return null;
492 }
493 String[] confs = conf.split(",");
494 for (int i = 0; i < confs.length; i++) {
495 confs[i] = confs[i].trim();
496 }
497 return confs;
498 }
499
500457 // CheckStyle:ParameterNumberCheck ON
501458 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 import java.util.Arrays;
3030 import java.util.Collection;
3131 import java.util.Collections;
32 import java.util.Iterator;
3332 import java.util.LinkedHashSet;
3433 import java.util.List;
3534 import java.util.StringTokenizer;
4443 import org.apache.ivy.core.report.ArtifactDownloadReport;
4544 import org.apache.ivy.core.report.ResolveReport;
4645 import org.apache.ivy.core.resolve.ResolveOptions;
46 import org.apache.ivy.core.resolve.ResolveProcessException;
4747 import org.apache.ivy.core.retrieve.RetrieveOptions;
4848 import org.apache.ivy.core.settings.IvySettings;
49 import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorWriter;
50 import org.apache.ivy.plugins.parser.m2.PomWriterOptions;
4951 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
5052 import org.apache.ivy.plugins.report.XmlReportParser;
5153 import org.apache.ivy.util.DefaultMessageLogger;
5254 import org.apache.ivy.util.Message;
55 import org.apache.ivy.util.PropertiesFile;
5356 import org.apache.ivy.util.cli.CommandLine;
5457 import org.apache.ivy.util.cli.CommandLineParser;
5558 import org.apache.ivy.util.cli.OptionBuilder;
5659 import org.apache.ivy.util.cli.ParseException;
5760 import org.apache.ivy.util.filter.FilterHelper;
5861 import org.apache.ivy.util.url.CredentialsStore;
59 import org.apache.ivy.util.url.URLHandler;
62 import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
6063 import org.apache.ivy.util.url.URLHandlerDispatcher;
6164 import org.apache.ivy.util.url.URLHandlerRegistry;
6265
7578 new OptionBuilder("settings").arg("settingsfile")
7679 .description("use given file for settings").create())
7780 .addOption(
81 new OptionBuilder("properties").arg("propertiesfile")
82 .description("use given file for properties not specified in settings").create())
83 .addOption(
7884 new OptionBuilder("cache").arg("cachedir")
7985 .description("use given directory for cache").create())
8086 .addOption(
8187 new OptionBuilder("novalidate").description(
8288 "do not validate ivy files against xsd").create())
8389 .addOption(
84 new OptionBuilder("m2compatible").description("use maven2 compatibility")
90 new OptionBuilder("m2compatible").description("use Maven 2 compatibility")
8591 .create())
8692 .addOption(
8793 new OptionBuilder("conf").arg("settingsfile").deprecated()
114120 .description("resolve given configurations").create())
115121 .addOption(
116122 new OptionBuilder("types").arg("types").countArgs(false)
117 .description("comma separated list of accepted artifact types")
123 .description("accepted artifact types")
118124 .create())
119125 .addOption(
120126 new OptionBuilder("mode").arg("resolvemode")
134140 new OptionBuilder("sync").description("use sync mode for retrieve").create())
135141 .addOption(
136142 new OptionBuilder("symlink").description("create symbolic links").create())
137
143 .addOption(new OptionBuilder("overwriteMode").arg("overwriteMode")
144 .description("use given overwrite mode for retrieve")
145 .create())
138146 .addCategory("cache path options")
139147 .addOption(
140148 new OptionBuilder("cachepath")
167175 new OptionBuilder("overwrite").description(
168176 "overwrite files in the repository if they exist").create())
169177
178 .addCategory("makepom options")
179 .addOption(new OptionBuilder("makepom").arg("pomfilepath")
180 .description("create a POM file for the module").create())
181
170182 .addCategory("http auth options")
171183 .addOption(
172184 new OptionBuilder("realm").arg("realm")
192204 new OptionBuilder("cp").arg("cp")
193205 .description("extra classpath to use when launching process").create())
194206
207
195208 .addCategory("message options")
196209 .addOption(
197210 new OptionBuilder("debug").description("set message level to debug").create())
213226 }
214227
215228 public static void main(String[] args) throws Exception {
216 CommandLineParser parser = getParser();
217229 try {
218 run(parser, args);
230 run(args, true);
219231 System.exit(0);
220232 } catch (ParseException ex) {
221233 System.err.println(ex.getMessage());
234 System.exit(1);
235 }
236 }
237
238 /**
239 * A method that allows to run embedded Ivy as if it were launched from CLI
240 * (e.g., for use with REPL in Java 9+).
241 *
242 * @param args an array of command line arguments
243 * @return null if asked for usage or version, or if anything fails during resolve, publish or
244 * launch; a ResolveReport on success
245 * @throws Exception if something goes wrong
246 */
247 public static ResolveReport run(String[] args) throws Exception {
248 return run(args, false);
249 }
250
251 /*
252 * For backwards compatibility and testing
253 */
254 static void run(CommandLineParser parser, String[] args) throws Exception {
255 if (Arrays.asList(args).contains("-?")) {
222256 usage(parser, false);
223 System.exit(1);
224 }
225 }
226
227 static void run(CommandLineParser parser, String[] args) throws Exception {
257 return;
258 }
259
260 run(parser.parse(args), true);
261 }
262
263 private static ResolveReport run(String[] args, boolean isCli) throws Exception {
264 CommandLineParser parser = getParser();
265
228266 // parse the command line arguments
229 CommandLine line = parser.parse(args);
267 CommandLine line;
268 try {
269 line = parser.parse(args);
270 } catch (ParseException pe) {
271 // display usage and and rethrow
272 usage(parser, false);
273 throw new ParseException(pe.getMessage());
274 }
230275
231276 if (line.hasOption("?")) {
232277 usage(parser, line.hasOption("deprecated"));
233 return;
234 }
235
278 return null;
279 }
280
281 return run(line, isCli);
282 }
283
284 @SuppressWarnings("deprecation")
285 private static ResolveReport run(CommandLine line, boolean isCli) throws Exception {
236286 if (line.hasOption("version")) {
237287 System.out.println("Apache Ivy " + Ivy.getIvyVersion() + " - " + Ivy.getIvyDate()
238288 + " :: " + Ivy.getIvyHomeURL());
239 return;
240 }
241
242 boolean validate = line.hasOption("novalidate") ? false : true;
289 return null;
290 }
291
292 boolean validate = !line.hasOption("novalidate");
243293
244294 Ivy ivy = Ivy.newInstance();
245295 initMessage(line, ivy);
277327 "working"));
278328 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
279329 ModuleRevisionId.newInstance(dep[0], dep[1], dep[2]), false, false, true);
280 for (int i = 0; i < confs.length; i++) {
281 dd.addDependencyConfiguration("default", confs[i]);
330 for (String conf : confs) {
331 dd.addDependencyConfiguration("default", conf);
282332 }
283333 md.addDependency(dd);
284334 XmlModuleDescriptorWriter.write(md, ivyfile);
309359 }
310360 ResolveReport report = ivy.resolve(ivyfile.toURI().toURL(), resolveOptions);
311361 if (report.hasError()) {
312 System.exit(1);
362 if (isCli) {
363 System.exit(1);
364 }
365
366 StringBuilder sb = new StringBuilder();
367 for (String problem : report.getAllProblemMessages()) {
368 if (sb.length() > 0) {
369 sb.append("\n");
370 }
371 sb.append(problem);
372 }
373 throw new ResolveProcessException(sb.toString());
313374 }
314375 ModuleDescriptor md = report.getModuleDescriptor();
315376
318379 }
319380 if (line.hasOption("retrieve")) {
320381 String retrievePattern = settings.substitute(line.getOptionValue("retrieve"));
321 if (retrievePattern.indexOf("[") == -1) {
322 retrievePattern = retrievePattern + "/lib/[conf]/[artifact].[ext]";
382 if (!retrievePattern.contains("[")) {
383 retrievePattern += "/lib/[conf]/[artifact].[ext]";
323384 }
324385 String ivyPattern = settings.substitute(line.getOptionValue("ivypattern"));
325386 ivy.retrieve(
326387 md.getModuleRevisionId(),
327 retrievePattern,
328388 new RetrieveOptions()
329389 .setConfs(confs)
330390 .setSync(line.hasOption("sync"))
331391 .setUseOrigin(line.hasOption("useOrigin"))
392 .setDestArtifactPattern(retrievePattern)
332393 .setDestIvyPattern(ivyPattern)
394 .setOverwriteMode(line.getOptionValue("overwriteMode"))
333395 .setArtifactFilter(
334396 FilterHelper.getArtifactTypeFilter(line.getOptionValues("types")))
335397 .setMakeSymlinks(line.hasOption("symlink"))
363425 .setOverwrite(line.hasOption("overwrite")));
364426 }
365427 }
428 if (line.hasOption("makepom")) {
429 final String pomFilePath = line.getOptionValue("makepom", "pom.xml");
430 final File pomFile = new File(pomFilePath);
431 PomModuleDescriptorWriter.write(md, pomFile, new PomWriterOptions());
432 Message.debug("Generated a pom file for module at " + pomFile);
433 }
366434 if (line.hasOption("main")) {
367435 // check if the option cp has been set
368 List fileList = getExtraClasspathFileList(line);
436 List<File> fileList = getExtraClasspathFileList(line);
369437
370438 // merge -args and left over args
371439 String[] fargs = line.getOptionValues("args");
384452 }
385453 ivy.getLoggerEngine().popLogger();
386454 ivy.popContext();
455
456 return report;
387457 }
388458
389459 /**
392462 * All the files contained in the returned List exist, non existing files are simply skipped
393463 * with a warning.
394464 * </p>
395 *
465 *
396466 * @param line
397 * the command line in which the cp option shold be parsed
467 * the command line in which the cp option should be parsed
398468 * @return a List of files to include as extra classpath entries, or <code>null</code> if no cp
399469 * option was provided.
400470 */
401 private static List/* <File> */getExtraClasspathFileList(CommandLine line) {
402 List fileList = null;
471 private static List<File> getExtraClasspathFileList(CommandLine line) {
472 List<File> fileList = null;
403473 if (line.hasOption("cp")) {
404 fileList = new ArrayList/* <File> */();
405 String[] cpArray = line.getOptionValues("cp");
406 for (int index = 0; index < cpArray.length; index++) {
407 StringTokenizer tokenizer = new StringTokenizer(cpArray[index],
408 System.getProperty("path.separator"));
474 fileList = new ArrayList<>();
475 for (String cp : line.getOptionValues("cp")) {
476 StringTokenizer tokenizer = new StringTokenizer(cp, File.pathSeparator);
409477 while (tokenizer.hasMoreTokens()) {
410478 String token = tokenizer.nextToken();
411479 File file = new File(token);
425493 throws java.text.ParseException, IOException, ParseException {
426494 IvySettings settings = ivy.getSettings();
427495 settings.addAllVariables(System.getProperties());
496 if (line.hasOption("properties")) {
497 settings.addAllVariables(new PropertiesFile(new File(line.getOptionValue("properties")),
498 "additional properties"));
499 }
428500 if (line.hasOption("m2compatible")) {
429501 settings.setVariable("ivy.default.configuration.m2compatible", "true");
430502 }
470542 private static void outputCachePath(Ivy ivy, File cache, ModuleDescriptor md, String[] confs,
471543 String outFile) {
472544 try {
473 String pathSeparator = System.getProperty("path.separator");
474 StringBuffer buf = new StringBuffer();
475 Collection all = new LinkedHashSet();
545 StringBuilder buf = new StringBuilder();
546 Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
476547 ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager();
477548 XmlReportParser parser = new XmlReportParser();
478 for (int i = 0; i < confs.length; i++) {
549 for (String conf : confs) {
479550 String resolveId = ResolveOptions.getDefaultResolveId(md);
480 File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]);
551 File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
481552 parser.parse(report);
482553
483554 all.addAll(Arrays.asList(parser.getArtifactReports()));
484555 }
485 for (Iterator iter = all.iterator(); iter.hasNext();) {
486 ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next();
556 for (ArtifactDownloadReport artifact : all) {
487557 if (artifact.getLocalFile() != null) {
488558 buf.append(artifact.getLocalFile().getCanonicalPath());
489 buf.append(pathSeparator);
559 buf.append(File.pathSeparator);
490560 }
491561 }
492562
493563 PrintWriter writer = new PrintWriter(new FileOutputStream(outFile));
494564 if (buf.length() > 0) {
495 writer.println(buf.substring(0, buf.length() - pathSeparator.length()));
565 buf.setLength(buf.length() - File.pathSeparator.length());
566 writer.println(buf);
496567 }
497568 writer.close();
498569 System.out.println("cachepath output to " + outFile);
502573 }
503574 }
504575
576 @SuppressWarnings("resource")
505577 private static void invoke(Ivy ivy, File cache, ModuleDescriptor md, String[] confs,
506 List fileList, String mainclass, String[] args) {
507 List urls = new ArrayList();
578 List<File> fileList, String mainclass, String[] args) {
579 List<URL> urls = new ArrayList<>();
508580
509581 // Add option cp (extra classpath) urls
510582 if (fileList != null && fileList.size() > 0) {
511 for (Iterator iter = fileList.iterator(); iter.hasNext();) {
512 File file = (File) iter.next();
583 for (File file : fileList) {
513584 try {
514585 urls.add(file.toURI().toURL());
515586 } catch (MalformedURLException e) {
519590 }
520591
521592 try {
522 Collection all = new LinkedHashSet();
593 Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
523594 ResolutionCacheManager cacheMgr = ivy.getResolutionCacheManager();
524595 XmlReportParser parser = new XmlReportParser();
525 for (int i = 0; i < confs.length; i++) {
596 for (String conf : confs) {
526597 String resolveId = ResolveOptions.getDefaultResolveId(md);
527 File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]);
598 File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
528599 parser.parse(report);
529600
530601 all.addAll(Arrays.asList(parser.getArtifactReports()));
531602 }
532 for (Iterator iter = all.iterator(); iter.hasNext();) {
533 ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next();
534
603 for (ArtifactDownloadReport artifact : all) {
535604 if (artifact.getLocalFile() != null) {
536605 urls.add(artifact.getLocalFile().toURI().toURL());
537606 }
540609 throw new RuntimeException("impossible to build ivy cache path: " + ex.getMessage(), ex);
541610 }
542611
543 URLClassLoader classLoader = new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]),
544 Main.class.getClassLoader());
612 URLClassLoader classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]),
613 Main.class.getClassLoader().getParent());
545614
546615 try {
547 Class c = classLoader.loadClass(mainclass);
548
549 Method mainMethod = c.getMethod("main", new Class[] {String[].class});
616 Class<?> c = classLoader.loadClass(mainclass);
617
618 Method mainMethod = c.getMethod("main", String[].class);
550619
551620 Thread.currentThread().setContextClassLoader(classLoader);
552621 mainMethod.invoke(null, new Object[] {(args == null ? new String[0] : args)});
553622 } catch (ClassNotFoundException cnfe) {
554623 throw new RuntimeException("Could not find class: " + mainclass, cnfe);
555 } catch (SecurityException e) {
556 throw new RuntimeException("Could not find main method: " + mainclass, e);
557 } catch (NoSuchMethodException e) {
624 } catch (SecurityException | NoSuchMethodException e) {
558625 throw new RuntimeException("Could not find main method: " + mainclass, e);
559626 } catch (IllegalAccessException e) {
560627 throw new RuntimeException("No permissions to invoke main method: " + mainclass, e);
568635 CredentialsStore.INSTANCE.addCredentials(realm, host, username, passwd);
569636
570637 URLHandlerDispatcher dispatcher = new URLHandlerDispatcher();
571 URLHandler httpHandler = URLHandlerRegistry.getHttp();
638 TimeoutConstrainedURLHandler httpHandler = URLHandlerRegistry.getHttp();
572639 dispatcher.setDownloader("http", httpHandler);
573640 dispatcher.setDownloader("https", httpHandler);
574641 URLHandlerRegistry.setDefault(dispatcher);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.util.ArrayList;
2121 import java.util.Collection;
22 import java.util.Iterator;
2322 import java.util.Map;
2423
2524 import org.apache.ivy.core.IvyContext;
3433 import org.apache.tools.ant.taskdefs.Property;
3534
3635 /**
37 * Triggers an ant build on an event occurence.
36 * Triggers an ant build on an event occurrence.
3837 * <p>
3938 * Example of use:
40 *
39 * </p>
4140 * <pre>
42 * &lt;ant-build-trigger event=&quot;pre-resolve-dependency&quot;
41 * &lt;ant-build-trigger event=&quot;pre-resolve-dependency&quot;
4342 * filter=&quot;revision=latest.integration&quot;
44 * antfile=&quot;/path/to/[module]/build.xml&quot;
43 * antfile=&quot;/path/to/[module]/build.xml&quot;
4544 * target=&quot;compile&quot;/&gt;
4645 * </pre>
47 *
46 * <p>
4847 * Triggers an ant build for any dependency in asked in latest.integration, just before resolving
4948 * the dependency.
5049 * </p>
5251 * The onlyonce property is used to tell if the ant build should be triggered only once, or several
5352 * times in the same build.
5453 * </p>
55 *
54 *
5655 * @see AntCallTrigger
5756 * @since 1.4
5857 */
6160
6261 private String target = null;
6362
64 private Collection builds = new ArrayList();
63 private Collection<String> builds = new ArrayList<>();
6564
6665 private String buildFilePattern;
6766
9089 if (target != null) {
9190 ant.setTarget(target);
9291 }
93 Map atts = event.getAttributes();
94 for (Iterator iter = atts.keySet().iterator(); iter.hasNext();) {
95 String key = (String) iter.next();
96 String value = (String) atts.get(key);
97 if (value != null) {
92 for (Map.Entry<String, String> entry : event.getAttributes().entrySet()) {
93 if (entry.getValue() != null) {
9894 Property p = ant.createProperty();
99 p.setName(prefix == null ? key : prefix + key);
100 p.setValue(value);
95 p.setName(prefix == null ? entry.getKey() : prefix + entry.getKey());
96 p.setValue(entry.getValue());
10197 }
10298 }
10399
127123 }
128124
129125 private File getBuildFile(IvyEvent event) {
130 return IvyContext
131 .getContext()
132 .getSettings()
133 .resolveFile(
134 IvyPatternHelper.substituteTokens(getBuildFilePattern(), event.getAttributes()));
126 return IvyContext.getContext().getSettings().resolveFile(
127 IvyPatternHelper.substituteTokens(getBuildFilePattern(), event.getAttributes()));
135128 }
136129
137130 public String getBuildFilePattern() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.Collection;
21 import java.util.Iterator;
2221 import java.util.Map;
2322
2423 import org.apache.ivy.core.IvyContext;
3231 import org.apache.tools.ant.taskdefs.Property;
3332
3433 /**
35 * Triggers an call to an ant target on an event occurence.
34 * Triggers an call to an ant target on an event occurrence.
3635 * <p>
3736 * This trigger only works when ivy is called from an ant build file, otherwise the trigger only log
3837 * a failure.
3938 * <p>
4039 * Example of use in an ivysettings file:
41 *
40 *
4241 * <pre>
4342 * &lt;ant-call-trigger event=&quot;post-download-artifact&quot; filter=&quot;type=zip&quot;
4443 * target=&quot;unzip&quot;/&gt;
4544 * </pre>
46 *
45 *
4746 * Triggers a call to the target "unzip" for any downloaded artifact of type zip
48 *
47 *
4948 * @see AntBuildTrigger
5049 * @since 1.4
5150 */
5453
5554 private String target = null;
5655
57 private Collection calls = new ArrayList();
56 private Collection<IvyEvent> calls = new ArrayList<>();
5857
5958 private String prefix;
6059
7271 call.setProject(project);
7372 call.setTaskName("antcall");
7473
75 Map attributes = event.getAttributes();
74 Map<String, String> attributes = event.getAttributes();
7675 String target = IvyPatternHelper.substituteTokens(getTarget(), attributes);
7776 call.setTarget(target);
7877
79 for (Iterator iter = attributes.keySet().iterator(); iter.hasNext();) {
80 String key = (String) iter.next();
81 String value = (String) attributes.get(key);
78 for (Map.Entry<String, String> entry : attributes.entrySet()) {
8279 Property p = call.createParam();
83 p.setName(prefix == null ? key : prefix + key);
84 p.setValue(value == null ? "" : value);
80 p.setName(prefix == null ? entry.getKey() : prefix + entry.getKey());
81 p.setValue(entry.getValue() == null ? "" : entry.getValue());
8582 }
8683
8784 Message.verbose("triggering ant call: target=" + target + " for " + event);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3838 * The created instance will automatically be unregistered from the Ivy instance when the task
3939 * finishes.
4040 * </p>
41 *
41 *
4242 * @param task
4343 * the task the logger should use for logging
4444 * @param ivy
5050 && ((AntMessageLogger) current).task instanceof Task) {
5151 Task currentTask = (Task) ((AntMessageLogger) current).task;
5252
53 if ((currentTask.getTaskName() != null)
53 if (currentTask.getTaskName() != null
5454 && currentTask.getTaskName().equals(((Task) task).getTaskName())) {
5555 // The current AntMessageLogger already logs with the same
5656 // prefix as the given task. So we shouldn't do anything...
8080 }
8181
8282 public void taskFinished(BuildEvent event) {
83 // NB: There is somtimes task created by an other task
83 // NB: There is sometimes task created by an other task
8484 // in that case, we should not uninit Message. The log should stay associated
8585 // with the initial task, except if it was an antcall, ant or subant target
86 // NB2 : Testing the identity of the task is not enought, event.getTask() return
86 // NB2 : Testing the identity of the task is not enough, event.getTask() return
8787 // an instance of UnknownElement is wrapping the concrete instance
8888 stackDepth--;
8989 if (stackDepth == -1) {
102102
103103 private long lastProgressFlush = 0;
104104
105 private StringBuffer buf = new StringBuffer();
105 private StringBuilder buf = new StringBuilder();
106106
107107 /**
108 * Constructs a new AntMEssageImpl instance.
109 *
110 * @param antProjectComponent
108 * Constructs a new AntMessageImpl instance.
109 *
110 * @param task
111111 * the ant project component this message implementation should use for logging. Must
112112 * not be <code>null</code>.
113113 */
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.ant;
18
19 import java.io.File;
20 import java.net.MalformedURLException;
21 import java.net.URISyntaxException;
22 import java.net.URL;
23 import java.text.ParseException;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.util.HashMap;
27 import java.util.List;
28 import java.util.Map;
29
30 import org.apache.ivy.core.module.descriptor.Artifact;
31 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
32 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
33 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
34 import org.apache.ivy.core.report.ArtifactDownloadReport;
35 import org.apache.ivy.core.report.DownloadReport;
36 import org.apache.ivy.core.report.DownloadStatus;
37 import org.apache.ivy.core.resolve.DownloadOptions;
38 import org.apache.ivy.core.resolve.ResolveData;
39 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
40 import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
41 import org.apache.ivy.plugins.resolver.AbstractWorkspaceResolver;
42 import org.apache.ivy.util.Message;
43 import org.apache.tools.ant.BuildException;
44 import org.apache.tools.ant.types.DataType;
45 import org.apache.tools.ant.types.Resource;
46 import org.apache.tools.ant.types.ResourceCollection;
47 import org.apache.tools.ant.types.resources.FileResource;
48
49 public class AntWorkspaceResolver extends DataType {
50
51 public static final class WorkspaceArtifact {
52
53 private String name;
54
55 private String type;
56
57 private String ext;
58
59 private String path;
60
61 public void setName(String name) {
62 this.name = name;
63 }
64
65 public void setType(String type) {
66 this.type = type;
67 }
68
69 public void setExt(String ext) {
70 this.ext = ext;
71 }
72
73 public void setPath(String path) {
74 this.path = path;
75 }
76 }
77
78 private List<ResourceCollection> allResources = new ArrayList<>();
79
80 private boolean haltOnError = true;
81
82 private Resolver resolver;
83
84 private String name;
85
86 private List<WorkspaceArtifact> artifacts = new ArrayList<>();
87
88 public void setName(String name) {
89 this.name = name;
90 }
91
92 public void setHaltonerror(boolean haltOnError) {
93 this.haltOnError = haltOnError;
94 }
95
96 public void addConfigured(ResourceCollection resources) {
97 if (!resources.isFilesystemOnly()) {
98 throw new BuildException("Only filesystem resource collection is supported");
99 }
100 allResources.add(resources);
101 }
102
103 public WorkspaceArtifact createArtifact() {
104 WorkspaceArtifact a = new WorkspaceArtifact();
105 artifacts.add(a);
106 return a;
107 }
108
109 public Resolver getResolver() {
110 if (resolver == null) {
111 if (name == null) {
112 throw new BuildException("A name is required");
113 }
114 resolver = new Resolver();
115 resolver.setName(name);
116 }
117 return resolver;
118 }
119
120 private String getProjectName(File ivyFile) {
121 return ivyFile.getParentFile().getName();
122 }
123
124 private class Resolver extends AbstractWorkspaceResolver {
125
126 private Map<ModuleDescriptor, File> md2IvyFile;
127
128 private synchronized Map<ModuleDescriptor, File> getModuleDescriptors() {
129 if (md2IvyFile == null) {
130 md2IvyFile = new HashMap<>();
131 for (ResourceCollection resources : allResources) {
132 for (Resource resource : resources) {
133 File ivyFile = ((FileResource) resource).getFile();
134 try {
135 ModuleDescriptor md = ModuleDescriptorParserRegistry.getInstance()
136 .parseDescriptor(getParserSettings(), ivyFile.toURI().toURL(),
137 isValidate());
138 md2IvyFile.put(md, ivyFile);
139 Message.debug("Add " + md.getModuleRevisionId().getModuleId());
140 } catch (Exception ex) {
141 if (haltOnError) {
142 throw new BuildException("impossible to parse ivy file " + ivyFile
143 + " exception=" + ex, ex);
144 } else {
145 Message.warn("impossible to parse ivy file " + ivyFile
146 + " exception=" + ex.getMessage());
147 }
148 }
149 }
150 }
151 }
152 return md2IvyFile;
153 }
154
155 public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
156 throws ParseException {
157 for (Map.Entry<ModuleDescriptor, File> md : getModuleDescriptors().entrySet()) {
158 ResolvedModuleRevision rmr = checkCandidate(dd, md.getKey(),
159 getProjectName(md.getValue()));
160 if (rmr != null) {
161 return rmr;
162 }
163 }
164 return null;
165 }
166
167 @Override
168 protected List<Artifact> createWorkspaceArtifacts(ModuleDescriptor md) {
169 List<Artifact> res = new ArrayList<>();
170
171 for (WorkspaceArtifact wa : artifacts) {
172 String name = wa.name;
173 String type = wa.type;
174 String ext = wa.ext;
175 String path = wa.path;
176 if (name == null) {
177 name = md.getModuleRevisionId().getName();
178 }
179 if (type == null) {
180 type = "jar";
181 }
182 if (ext == null) {
183 ext = "jar";
184 }
185 if (path == null) {
186 path = "target" + File.separator + "dist" + File.separator + type + "s"
187 + File.separator + name + "." + ext;
188 }
189
190 URL url;
191 File ivyFile = md2IvyFile.get(md);
192 File artifactFile = new File(ivyFile.getParentFile(), path);
193 try {
194 url = artifactFile.toURI().toURL();
195 } catch (MalformedURLException e) {
196 throw new RuntimeException("Unsupported file path : " + artifactFile, e);
197 }
198
199 res.add(new DefaultArtifact(md.getModuleRevisionId(), new Date(), name, type, ext,
200 url, null));
201 }
202
203 return res;
204 }
205
206 public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
207 // Not much to do here - downloads are not required for workspace projects.
208 DownloadReport dr = new DownloadReport();
209 for (Artifact artifact : artifacts) {
210 ArtifactDownloadReport adr = new ArtifactDownloadReport(artifact);
211 dr.addArtifactReport(adr);
212 URL url = artifact.getUrl();
213 if (url == null || !url.getProtocol().equals("file")) {
214 // this is not an artifact managed by this resolver
215 adr.setDownloadStatus(DownloadStatus.FAILED);
216 return dr;
217 }
218 File f;
219 try {
220 f = new File(url.toURI());
221 } catch (URISyntaxException e) {
222 f = new File(url.getPath());
223 }
224 adr.setLocalFile(f);
225 adr.setDownloadStatus(DownloadStatus.NO);
226 adr.setSize(0);
227 Message.verbose("\t[IN WORKSPACE] " + artifact);
228 }
229 return dr;
230 }
231 }
232
233 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
104104 && !sourceTypes.isEmpty()) {
105105 StringBuilder buffer = new StringBuilder(getType());
106106 for (String sourceType : sourceTypes) {
107 buffer.append(",");
108 buffer.append(sourceType);
107 buffer.append(",").append(sourceType);
109108 }
110109 setType(buffer.toString());
111110 }
160159 } catch (ParseException e) {
161160 throw new BuildException("Impossible to parse the artifact reports: "
162161 + e.getMessage(), e);
163 } catch (IOException e) {
164 throw new BuildException("Impossible to read the artifact reports: "
165 + e.getMessage(), e);
166162 }
167163 }
168164
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3131
3232 private File dest;
3333
34 private List/* <Keep> */keeps = new ArrayList();
34 private List<Keep> keeps = new ArrayList<>();
3535
3636 public void setToFile(File dest) {
3737 this.dest = dest;
5858 return k;
5959 }
6060
61 @Override
6162 public void doExecute() throws BuildException {
6263 prepareAndCheck();
6364
7172
7273 ResolveReport report = getResolvedReport();
7374
74 List/* <ModuleId> */midToKeep = new ArrayList();
75 for (int i = 0; i < keeps.size(); i++) {
76 midToKeep.add(ModuleId.newInstance(((Keep) keeps.get(i)).org,
77 ((Keep) keeps.get(i)).module));
75 List<ModuleId> midToKeep = new ArrayList<>();
76 for (Keep keep : keeps) {
77 midToKeep.add(ModuleId.newInstance(keep.org, keep.module));
7878 }
7979
8080 ModuleDescriptor md = report.toFixedModuleDescriptor(getSettings(), midToKeep);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 import org.apache.ivy.core.settings.IvyVariableContainer;
3030 import org.apache.ivy.util.Message;
3131 import org.apache.ivy.util.url.CredentialsStore;
32 import org.apache.ivy.util.url.URLHandler;
32 import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
3333 import org.apache.ivy.util.url.URLHandlerDispatcher;
3434 import org.apache.ivy.util.url.URLHandlerRegistry;
3535 import org.apache.tools.ant.BuildException;
3939 import org.apache.tools.ant.taskdefs.Property;
4040 import org.apache.tools.ant.types.DataType;
4141
42 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
43
4244 public class IvyAntSettings extends DataType {
4345
4446 public static class Credentials {
100102 private String id = "ivy.instance";
101103
102104 private boolean autoRegistered = false;
105
106 private AntWorkspaceResolver antWorkspaceResolver;
103107
104108 /**
105109 * Returns the default ivy settings of this classloader. If it doesn't exist yet, a new one is
106110 * created using the given project to back the VariableContainer.
107 *
108 * @param project
111 *
112 * @param task
109113 * TODO add text.
110114 * @return An IvySetting instance.
111115 */
189193 super.setProject(p);
190194
191195 if ("ivy.instance".equals(id) && !getProject().getReferences().containsKey(id)) {
192 // register ourselfs as default settings, just in case the id attribute is not set
196 // register ourselves as default settings, just in case the id attribute is not set
193197 getProject().addReference("ivy.instance", this);
194198 autoRegistered = true;
195199 }
196200 }
197201
198202 private static String format(String str) {
199 return str == null ? str : (str.trim().length() == 0 ? null : str.trim());
203 return isNullOrEmpty(str) ? null : str.trim();
200204 }
201205
202206 public void addConfiguredCredentials(Credentials c) {
238242
239243 /**
240244 * Return the configured Ivy instance.
241 *
245 *
246 * @param task ProjectComponent
242247 * @return Returns the configured Ivy instance.
243248 */
244249 public Ivy getConfiguredIvyInstance(ProjectComponent task) {
272277
273278 if (file == null && url == null) {
274279 defineDefaultSettingFile(ivyAntVariableContainer, task);
280 }
281
282 if (antWorkspaceResolver != null) {
283 settings.addConfigured(antWorkspaceResolver.getResolver());
275284 }
276285
277286 Ivy ivy = Ivy.newInstance(settings);
296305 }
297306 ivyAntVariableContainer.updateProject(id);
298307 ivyEngine = ivy;
299 } catch (ParseException e) {
300 throw new BuildException("impossible to configure ivy:settings with given "
301 + (file != null ? "file: " + file : "url: " + url) + " : " + e, e);
302 } catch (IOException e) {
308 } catch (ParseException | IOException e) {
303309 throw new BuildException("impossible to configure ivy:settings with given "
304310 + (file != null ? "file: " + file : "url: " + url) + " : " + e, e);
305311 } finally {
312318 // this is copy of loadURL code from ant Property task (not available in 1.5.1)
313319 Properties props = new Properties();
314320 task.log("Loading " + url, Project.MSG_VERBOSE);
315 try {
316 InputStream is = url.openStream();
317 try {
318 props.load(is);
319 } finally {
320 if (is != null) {
321 is.close();
322 }
323 }
321 try (InputStream is = url.openStream()) {
322 props.load(is);
324323 } catch (IOException ex) {
325324 throw new BuildException(ex);
326325 }
329328
330329 /**
331330 * Set file or url to its default value
332 *
333 * @param variableContainer
331 *
332 * @param variableContainer IvyVariableContainer
334333 */
335334 private void defineDefaultSettingFile(IvyVariableContainer variableContainer,
336335 ProjectComponent task) {
346345 new File(getProject().getBaseDir(), settingsFileName),
347346 new File(getProject().getBaseDir(), "ivyconf.xml"), new File(settingsFileName),
348347 new File("ivyconf.xml")};
349 for (int i = 0; i < settingsLocations.length; i++) {
350 file = settingsLocations[i];
351 task.log("searching settings file: trying " + file, Project.MSG_VERBOSE);
352 if (file.exists()) {
348 for (File settingsFile : settingsLocations) {
349 task.log("searching settings file: trying " + settingsFile, Project.MSG_VERBOSE);
350 if (settingsFile.exists()) {
351 file = settingsFile;
353352 break;
354353 }
355354 }
356 if (!file.exists()) {
357 file = null;
358 if (Boolean.valueOf(getProject().getProperty("ivy.14.compatible")).booleanValue()) {
355 if (file == null) {
356 if (Boolean.valueOf(getProject().getProperty("ivy.14.compatible"))) {
359357 task.log("no settings file found, using Ivy 1.4 default...", Project.MSG_VERBOSE);
360358 url = IvySettings.getDefault14SettingsURL();
361359 } else {
381379 CredentialsStore.INSTANCE.addCredentials(getRealm(), getHost(), getUsername(), getPasswd());
382380
383381 URLHandlerDispatcher dispatcher = new URLHandlerDispatcher();
384 URLHandler httpHandler = URLHandlerRegistry.getHttp();
382 TimeoutConstrainedURLHandler httpHandler = URLHandlerRegistry.getHttp();
385383 dispatcher.setDownloader("http", httpHandler);
386384 dispatcher.setDownloader("https", httpHandler);
387385 URLHandlerRegistry.setDefault(dispatcher);
388386 }
389387
388 public void addConfiguredWorkspaceResolver(AntWorkspaceResolver antWorkspaceResolver) {
389 this.antWorkspaceResolver = antWorkspaceResolver;
390 }
390391 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.ant;
1818
1919 import java.util.HashMap;
20 import java.util.Iterator;
2120 import java.util.Map;
22 import java.util.Map.Entry;
2321
2422 import org.apache.ivy.core.settings.IvyVariableContainer;
2523 import org.apache.ivy.core.settings.IvyVariableContainerImpl;
2927
3028 class IvyAntVariableContainer extends IvyVariableContainerImpl implements IvyVariableContainer {
3129
32 private Map overwrittenProperties = new HashMap();
30 private Map<String, String> overwrittenProperties = new HashMap<>();
3331
3432 private Project project;
3533
3836 }
3937
4038 public String getVariable(String name) {
41 String r = (String) overwrittenProperties.get(name);
39 String r = overwrittenProperties.get(name);
4240 if (r == null) {
4341 r = project.getProperty(name);
4442 }
5957
6058 /**
6159 * Updates the Ant Project used in this container with variables set in Ivy.
62 *
60 *
6361 * All variables defined in Ivy will be set in the Ant project under two names:
6462 * <ul>
6563 * <li>the name of the variable</li>
66 * <li>the name of the variable suffxied with a dot + the given id, if the given id is not null</li>
64 * <li>the name of the variable suffixed with a dot + the given id, if the given id is not null
65 * </li>
6766 * </ul>
68 *
67 *
6968 * @param id
7069 * The identifier of the settings in which the variables have been set, which should
7170 * be used as property names suffix
7271 */
7372 public void updateProject(String id) {
74 Map r = new HashMap(super.getVariables());
73 Map<String, String> r = new HashMap<>(super.getVariables());
7574 r.putAll(overwrittenProperties);
76 for (Iterator it = r.entrySet().iterator(); it.hasNext();) {
77 Entry entry = (Entry) it.next();
78
79 setPropertyIfNotSet((String) entry.getKey(), (String) entry.getValue());
75 for (Map.Entry<String, String> entry : r.entrySet()) {
76 setPropertyIfNotSet(entry.getKey(), entry.getValue());
8077 if (id != null) {
81 setPropertyIfNotSet((String) entry.getKey() + "." + id, (String) entry.getValue());
78 setPropertyIfNotSet(entry.getKey() + "." + id, entry.getValue());
8279 }
8380 }
8481
9794 }
9895 }
9996
97 @SuppressWarnings("unchecked")
10098 public Object clone() {
10199 IvyAntVariableContainer result = (IvyAntVariableContainer) super.clone();
102 result.overwrittenProperties = (HashMap) ((HashMap) this.overwrittenProperties).clone();
100 result.overwrittenProperties = (HashMap<String, String>) ((HashMap<String, String>) this.overwrittenProperties)
101 .clone();
103102 return result;
104103 }
105104 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import org.apache.ivy.core.resolve.ResolveOptions;
2525 import org.apache.ivy.plugins.report.XmlReportParser;
2626 import org.apache.tools.ant.BuildException;
27
28 import static org.apache.ivy.util.StringUtils.splitToArray;
2729
2830 /**
2931 * Set a set of ant properties according to the last artifact resolved
6163
6264 try {
6365 ResolutionCacheManager cacheMgr = getIvyInstance().getResolutionCacheManager();
64 String[] confs = splitConfs(getConf());
6566 String resolveId = getResolveId();
6667 if (resolveId == null) {
6768 resolveId = ResolveOptions.getDefaultResolveId(getResolvedModuleId());
6869 }
6970 XmlReportParser parser = new XmlReportParser();
70 for (int i = 0; i < confs.length; i++) {
71 File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]);
71 for (String conf : splitToArray(getConf())) {
72 File report = cacheMgr.getConfigurationResolveReportInCache(resolveId, conf);
7273 parser.parse(report);
7374
74 Artifact[] artifacts = parser.getArtifacts();
75 for (int j = 0; j < artifacts.length; j++) {
76 Artifact artifact = artifacts[j];
75 for (Artifact artifact : parser.getArtifacts()) {
7776 String name = IvyPatternHelper.substitute(getSettings().substitute(getName()),
78 artifact, confs[i]);
77 artifact, conf);
7978 String value = IvyPatternHelper.substitute(
80 getSettings().substitute(getValue()), artifact, confs[i]);
79 getSettings().substitute(getValue()), artifact, conf);
8180 setProperty(name, value);
8281 }
8382 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.text.ParseException;
2323 import java.util.HashMap;
2424 import java.util.HashSet;
25 import java.util.Iterator;
2625 import java.util.Map;
2726 import java.util.Set;
2827
4847 import org.xml.sax.SAXException;
4948 import org.xml.sax.helpers.AttributesImpl;
5049
50 import static org.apache.ivy.util.StringUtils.splitToArray;
51
5152 /**
5253 * Generates a report of all artifacts involved during the last resolve.
5354 */
8283 pattern = getProperty(pattern, getSettings(), "ivy.retrieve.pattern");
8384
8485 try {
85 String[] confs = splitConfs(getConf());
86 String[] confs = splitToArray(getConf());
8687 ModuleDescriptor md = null;
87 if (getResolveId() != null) {
88 md = (ModuleDescriptor) getResolvedDescriptor(getResolveId());
88 if (getResolveId() == null) {
89 md = getResolvedDescriptor(getOrganisation(), getModule(), false);
8990 } else {
90 md = (ModuleDescriptor) getResolvedDescriptor(getOrganisation(), getModule(), false);
91 }
92 IvyNode[] dependencies = getIvyInstance().getResolveEngine().getDependencies(
93 md,
91 md = getResolvedDescriptor(getResolveId());
92 }
93 IvyNode[] dependencies = getIvyInstance().getResolveEngine().getDependencies(md,
9494 ((ResolveOptions) new ResolveOptions().setLog(getLog())).setConfs(confs)
9595 .setResolveId(getResolveId()).setValidate(doValidate(getSettings())), null);
9696
97 Map artifactsToCopy = getIvyInstance().getRetrieveEngine().determineArtifactsToCopy(
98 ModuleRevisionId.newInstance(getOrganisation(), getModule(), getRevision()),
99 pattern,
100 ((RetrieveOptions) new RetrieveOptions().setLog(getLog())).setConfs(confs)
101 .setResolveId(getResolveId()));
102
103 Map moduleRevToArtifactsMap = new HashMap();
104 for (Iterator iter = artifactsToCopy.keySet().iterator(); iter.hasNext();) {
105 ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next();
106 Set moduleRevArtifacts = (Set) moduleRevToArtifactsMap.get(artifact.getArtifact()
97 Map<ArtifactDownloadReport, Set<String>> artifactsToCopy = getIvyInstance().getRetrieveEngine()
98 .determineArtifactsToCopy(ModuleRevisionId.newInstance(getOrganisation(),
99 getModule(), getRevision()), pattern,
100 ((RetrieveOptions) new RetrieveOptions().setLog(getLog()))
101 .setConfs(confs).setResolveId(getResolveId()));
102
103 Map<ModuleRevisionId, Set<ArtifactDownloadReport>> moduleRevToArtifactsMap = new HashMap<>();
104 for (ArtifactDownloadReport artifact : artifactsToCopy.keySet()) {
105 Set<ArtifactDownloadReport> moduleRevArtifacts = moduleRevToArtifactsMap.get(artifact.getArtifact()
107106 .getModuleRevisionId());
108107 if (moduleRevArtifacts == null) {
109 moduleRevArtifacts = new HashSet();
108 moduleRevArtifacts = new HashSet<>();
110109 moduleRevToArtifactsMap.put(artifact.getArtifact().getModuleRevisionId(),
111110 moduleRevArtifacts);
112111 }
122121 }
123122 }
124123
125 private void generateXml(IvyNode[] dependencies, Map moduleRevToArtifactsMap,
126 Map artifactsToCopy) {
124 private void generateXml(IvyNode[] dependencies,
125 Map<ModuleRevisionId, Set<ArtifactDownloadReport>> moduleRevToArtifactsMap,
126 Map<ArtifactDownloadReport, Set<String>> artifactsToCopy) {
127127 try {
128 FileOutputStream fileOuputStream = new FileOutputStream(tofile);
129 try {
130 TransformerHandler saxHandler = createTransformerHandler(fileOuputStream);
128 try (FileOutputStream fileOutputStream = new FileOutputStream(tofile)) {
129 TransformerHandler saxHandler = createTransformerHandler(fileOutputStream);
131130
132131 saxHandler.startDocument();
133132 saxHandler.startElement(null, "modules", "modules", new AttributesImpl());
134133
135 for (int i = 0; i < dependencies.length; i++) {
136 IvyNode dependency = dependencies[i];
137 if (dependency.getModuleRevision() == null || dependency.isCompletelyEvicted()) {
134 for (IvyNode dependency : dependencies) {
135 if (dependency.getModuleRevision() == null
136 || dependency.isCompletelyEvicted()) {
138137 continue;
139138 }
140139
141140 startModule(saxHandler, dependency);
142141
143 Set artifactsOfModuleRev = (Set) moduleRevToArtifactsMap.get(dependency
142 Set<ArtifactDownloadReport> artifactsOfModuleRev = moduleRevToArtifactsMap.get(dependency
144143 .getModuleRevision().getId());
145144 if (artifactsOfModuleRev != null) {
146 for (Iterator iter = artifactsOfModuleRev.iterator(); iter.hasNext();) {
147 ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next();
145 for (ArtifactDownloadReport artifact : artifactsOfModuleRev) {
148146
149147 RepositoryCacheManager cache = dependency.getModuleRevision()
150148 .getArtifactResolver().getRepositoryCacheManager();
154152 writeOriginLocationIfPresent(cache, saxHandler, artifact);
155153 writeCacheLocationIfPresent(cache, saxHandler, artifact);
156154
157 Set artifactDestPaths = (Set) artifactsToCopy.get(artifact);
158 for (Iterator iterator = artifactDestPaths.iterator(); iterator
159 .hasNext();) {
160 String artifactDestPath = (String) iterator.next();
155 for (String artifactDestPath : artifactsToCopy.get(artifact)) {
161156 writeRetrieveLocation(saxHandler, artifactDestPath);
162157 }
163158 saxHandler.endElement(null, "artifact", "artifact");
167162 }
168163 saxHandler.endElement(null, "modules", "modules");
169164 saxHandler.endDocument();
170 } finally {
171 fileOuputStream.close();
172 }
173 } catch (SAXException e) {
165 }
166 } catch (SAXException | IOException | TransformerConfigurationException e) {
174167 throw new BuildException("impossible to generate report", e);
175 } catch (TransformerConfigurationException e) {
176 throw new BuildException("impossible to generate report", e);
177 } catch (IOException e) {
178 throw new BuildException("impossible to generate report", e);
179 }
180 }
181
182 private TransformerHandler createTransformerHandler(FileOutputStream fileOuputStream)
183 throws TransformerFactoryConfigurationError, TransformerConfigurationException,
184 SAXException {
168 }
169 }
170
171 private TransformerHandler createTransformerHandler(FileOutputStream fileOutputStream)
172 throws TransformerFactoryConfigurationError, TransformerConfigurationException {
185173 SAXTransformerFactory transformerFact = (SAXTransformerFactory) SAXTransformerFactory
186174 .newInstance();
187175 TransformerHandler saxHandler = transformerFact.newTransformerHandler();
188176 saxHandler.getTransformer().setOutputProperty(OutputKeys.ENCODING, "UTF-8");
189177 saxHandler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");
190 saxHandler.setResult(new StreamResult(fileOuputStream));
178 saxHandler.setResult(new StreamResult(fileOutputStream));
191179 return saxHandler;
192180 }
193181
213201 }
214202
215203 private void writeOriginLocationIfPresent(RepositoryCacheManager cache,
216 TransformerHandler saxHandler, ArtifactDownloadReport artifact) throws IOException,
217 SAXException {
204 TransformerHandler saxHandler, ArtifactDownloadReport artifact) throws SAXException {
218205 ArtifactOrigin origin = artifact.getArtifactOrigin();
219206 if (!ArtifactOrigin.isUnknown(origin)) {
220207 String originName = origin.getLocation();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.util.Collections;
2323 import java.util.HashMap;
2424 import java.util.HashSet;
25 import java.util.Iterator;
2625 import java.util.LinkedHashSet;
2726 import java.util.List;
28 import java.util.ListIterator;
2927 import java.util.Map;
3028 import java.util.Set;
3129 import java.util.StringTokenizer;
3230
3331 import org.apache.ivy.Ivy;
32 import org.apache.ivy.core.IvyPatternHelper;
3433 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3534 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3635 import org.apache.ivy.core.module.id.ModuleId;
3736 import org.apache.ivy.core.settings.IvySettings;
3837 import org.apache.ivy.core.sort.SortOptions;
38 import org.apache.ivy.plugins.matcher.MapMatcher;
39 import org.apache.ivy.plugins.matcher.PatternMatcher;
3940 import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
4041 import org.apache.ivy.util.Message;
4142 import org.apache.tools.ant.BuildException;
6364 }
6465 }
6566
67 public static final class BuildListModule {
68
69 private String organisation;
70
71 private String module;
72
73 private String revision;
74
75 private String branch;
76
77 private File file;
78
79 public String getOrganisation() {
80 return organisation;
81 }
82
83 public void setOrganisation(String organisation) {
84 this.organisation = organisation;
85 }
86
87 public String getModule() {
88 return module;
89 }
90
91 public void setModule(String module) {
92 this.module = module;
93 }
94
95 public String getRevision() {
96 return revision;
97 }
98
99 public void setRevision(String revision) {
100 this.revision = revision;
101 }
102
103 public String getBranch() {
104 return branch;
105 }
106
107 public void setBranch(String branch) {
108 this.branch = branch;
109 }
110
111 public File getFile() {
112 return file;
113 }
114
115 public void setFile(File file) {
116 this.file = file;
117 }
118
119 }
120
66121 public static final String DESCRIPTOR_REQUIRED = "required";
67122
68 private List buildFileSets = new ArrayList(); // List (FileSet)
123 private List<FileSet> buildFileSets = new ArrayList<>();
69124
70125 private String reference;
71126
79134
80135 private String root = "*";
81136
137 private List<BuildListModule> roots = new ArrayList<>();
138
82139 private boolean excludeRoot = false;
83140
84141 private String leaf = "*";
142
143 private List<BuildListModule> leafs = new ArrayList<>();
85144
86145 private String delimiter = ",";
87146
111170 this.root = root;
112171 }
113172
173 public BuildListModule createRoot() {
174 BuildListModule root = new BuildListModule();
175 roots.add(root);
176 return root;
177 }
178
114179 public boolean isExcludeRoot() {
115180 return excludeRoot;
116181 }
127192 this.leaf = leaf;
128193 }
129194
195 public BuildListModule createLeaf() {
196 BuildListModule leaf = new BuildListModule();
197 leafs.add(leaf);
198 return leaf;
199 }
200
130201 public boolean isExcludeLeaf() {
131202 return excludeLeaf;
132203 }
151222 this.onlydirectdep = onlydirectdep;
152223 }
153224
225 @Override
154226 public void doExecute() throws BuildException {
155227 if (reference == null) {
156228 throw new BuildException("reference should be provided in ivy build list");
167239
168240 Path path = new Path(getProject());
169241
170 Map buildFiles = new HashMap(); // Map (ModuleDescriptor -> File buildFile)
171 List independent = new ArrayList();
172 List noDescriptor = new ArrayList();
173 Collection mds = new ArrayList();
174
175 Set rootModuleNames = new LinkedHashSet();
176 if (!"*".equals(root)) {
177 StringTokenizer st = new StringTokenizer(root, delimiter);
178 while (st.hasMoreTokens()) {
179 rootModuleNames.add(st.nextToken());
180 }
181 }
182
183 Set leafModuleNames = new LinkedHashSet();
184 if (!"*".equals(leaf)) {
185 StringTokenizer st = new StringTokenizer(leaf, delimiter);
186 while (st.hasMoreTokens()) {
187 leafModuleNames.add(st.nextToken());
188 }
189 }
190
191 Set restartFromModuleNames = new LinkedHashSet();
192 if (!"*".equals(restartFrom)) {
193 StringTokenizer st = new StringTokenizer(restartFrom, delimiter);
194 // Only accept one (first) module
195 restartFromModuleNames.add(st.nextToken());
196 }
197
198 for (ListIterator iter = buildFileSets.listIterator(); iter.hasNext();) {
199 FileSet fs = (FileSet) iter.next();
242 Map<ModuleDescriptor, File> buildFiles = new HashMap<>();
243 List<File> independent = new ArrayList<>();
244 List<File> noDescriptor = new ArrayList<>();
245 Collection<ModuleDescriptor> mds = new ArrayList<>();
246
247 Set<MapMatcher> rootModules = convert(roots, root, settings);
248 Set<MapMatcher> leafModules = convert(leafs, leaf, settings);
249 Set<MapMatcher> restartFromModules = convert(Collections.<BuildListModule>emptyList(), restartFrom, settings);
250
251 for (FileSet fs : buildFileSets) {
200252 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
201 String[] builds = ds.getIncludedFiles();
202 for (int i = 0; i < builds.length; i++) {
203 File buildFile = new File(ds.getBasedir(), builds[i]);
253 for (String build : ds.getIncludedFiles()) {
254 File buildFile = new File(ds.getBasedir(), build);
204255 File ivyFile = getIvyFileFor(buildFile);
205256 if (!ivyFile.exists()) {
206257 onMissingDescriptor(buildFile, ivyFile, noDescriptor);
227278 }
228279 }
229280
230 List leafModuleDescriptors = convertModuleNamesToModuleDescriptors(mds, leafModuleNames,
231 "leaf");
232 List rootModuleDescriptors = convertModuleNamesToModuleDescriptors(mds, rootModuleNames,
233 "root");
234 List restartFromModuleDescriptors = convertModuleNamesToModuleDescriptors(mds,
235 restartFromModuleNames, "restartFrom");
281 List<ModuleDescriptor> leafModuleDescriptors =
282 findModuleDescriptors(mds, leafModules, "leaf");
283 List<ModuleDescriptor> rootModuleDescriptors =
284 findModuleDescriptors(mds, rootModules, "root");
285 List<ModuleDescriptor> restartFromModuleDescriptors =
286 findModuleDescriptors(mds, restartFromModules, "restartFrom");
236287
237288 if (!rootModuleDescriptors.isEmpty()) {
238 Message.info("Filtering modules based on roots " + rootModuleNames);
289 Message.info("Filtering modules based on roots [" + extractModuleNames(rootModules) + "]");
239290 mds = filterModulesFromRoot(mds, rootModuleDescriptors);
240291 }
241292 if (!leafModuleDescriptors.isEmpty()) {
242 Message.info("Filtering modules based on leafs " + leafModuleNames);
293 Message.info("Filtering modules based on leafs [" + extractModuleNames(leafModules) + "]");
243294 mds = filterModulesFromLeaf(mds, leafModuleDescriptors);
244295 }
245296
246 List sortedModules = ivy.sortModuleDescriptors(mds, SortOptions.DEFAULT);
297 List<ModuleDescriptor> sortedModules = ivy.sortModuleDescriptors(mds, SortOptions.DEFAULT);
247298
248299 if (!OnMissingDescriptor.TAIL.equals(onMissingDescriptor)) {
249 for (ListIterator iter = noDescriptor.listIterator(); iter.hasNext();) {
250 File buildFile = (File) iter.next();
300 for (File buildFile : noDescriptor) {
251301 addBuildFile(path, buildFile);
252302 }
253303 }
254 for (ListIterator iter = independent.listIterator(); iter.hasNext();) {
255 File buildFile = (File) iter.next();
304 for (File buildFile : independent) {
256305 addBuildFile(path, buildFile);
257306 }
258307 if (isReverse()) {
263312 // so they are not removed from build path.
264313 if (!restartFromModuleDescriptors.isEmpty()) {
265314 boolean foundRestartFrom = false;
266 List keptModules = new ArrayList();
267 ModuleDescriptor restartFromModuleDescriptor = (ModuleDescriptor) restartFromModuleDescriptors
268 .get(0);
269 for (ListIterator iter = sortedModules.listIterator(); iter.hasNext();) {
270 ModuleDescriptor md = (ModuleDescriptor) iter.next();
315 List<ModuleDescriptor> keptModules = new ArrayList<>();
316 // Only accept one (first) module
317 ModuleDescriptor restartFromModuleDescriptor = restartFromModuleDescriptors.get(0);
318 for (ModuleDescriptor md : sortedModules) {
271319 if (md.equals(restartFromModuleDescriptor)) {
272320 foundRestartFrom = true;
273321 }
277325 }
278326 sortedModules = keptModules;
279327 }
280 StringBuffer order = new StringBuffer();
281 for (ListIterator iter = sortedModules.listIterator(); iter.hasNext();) {
282 ModuleDescriptor md = (ModuleDescriptor) iter.next();
328 StringBuilder order = new StringBuilder();
329 for (ModuleDescriptor md : sortedModules) {
330 if (order.length() > 0) {
331 order.append(", ");
332 }
283333 order.append(md.getModuleRevisionId().getModuleId());
284 if (iter.hasNext()) {
285 order.append(", ");
286 }
287 File buildFile = (File) buildFiles.get(md);
288 addBuildFile(path, buildFile);
334 addBuildFile(path, buildFiles.get(md));
289335 }
290336 if (OnMissingDescriptor.TAIL.equals(onMissingDescriptor)) {
291 for (ListIterator iter = noDescriptor.listIterator(); iter.hasNext();) {
292 File buildFile = (File) iter.next();
337 for (File buildFile : noDescriptor) {
293338 addBuildFile(path, buildFile);
294339 }
295340 }
298343 getProject().setProperty("ivy.sorted.modules", order.toString());
299344 }
300345
301 private void onMissingDescriptor(File buildFile, File ivyFile, List noDescriptor) {
302 if (OnMissingDescriptor.SKIP.equals(onMissingDescriptor)) {
303 Message.debug("skipping " + buildFile + ": descriptor " + ivyFile + " doesn't exist");
304 } else if (OnMissingDescriptor.FAIL.equals(onMissingDescriptor)) {
305 throw new BuildException(
306 "a module has no module descriptor and onMissingDescriptor=fail. "
307 + "Build file: " + buildFile + ". Expected descriptor: " + ivyFile);
308 } else {
309 if (OnMissingDescriptor.WARN.equals(onMissingDescriptor)) {
346 private Set<MapMatcher> convert(List<BuildListModule> modulesList, String modulesString, IvySettings settings) {
347 Set<MapMatcher> result = new LinkedHashSet<>();
348
349 for (BuildListModule module : modulesList) {
350 File ivyFile = module.getFile();
351 if (ivyFile == null) {
352 String org = module.getOrganisation();
353 String name = module.getModule();
354 String rev = module.getRevision();
355 String branch = module.getBranch();
356
357 Map<String, String> attributes = new HashMap<>();
358 attributes.put(IvyPatternHelper.ORGANISATION_KEY, org == null ? PatternMatcher.ANY_EXPRESSION : org);
359 attributes.put(IvyPatternHelper.MODULE_KEY, name == null ? PatternMatcher.ANY_EXPRESSION : name);
360 attributes.put(IvyPatternHelper.MODULE_KEY, rev == null ? PatternMatcher.ANY_EXPRESSION : rev);
361 attributes.put(IvyPatternHelper.MODULE_KEY, branch == null ? PatternMatcher.ANY_EXPRESSION : branch);
362
363 result.add(new MapMatcher(attributes, settings.getMatcher(PatternMatcher.EXACT)));
364 } else {
365 try {
366 ModuleDescriptor md = ModuleDescriptorParserRegistry.getInstance()
367 .parseDescriptor(settings, ivyFile.toURI().toURL(),
368 doValidate(settings));
369
370 Map<String, String> attributes = new HashMap<>();
371 attributes.putAll(md.getModuleRevisionId().getAttributes());
372 attributes.put("resource", md.getResource().getName());
373
374 result.add(new MapMatcher(attributes, settings.getMatcher(PatternMatcher.EXACT)));
375 } catch (Exception e) {
376 throw new BuildException(e);
377 }
378 }
379 }
380
381 if (!"*".equals(modulesString)) {
382 StringTokenizer st = new StringTokenizer(modulesString, getDelimiter());
383 while (st.hasMoreTokens()) {
384 Map<String, String> attributes = new HashMap<>();
385 attributes.put(IvyPatternHelper.MODULE_KEY, st.nextToken());
386
387 result.add(new MapMatcher(attributes, settings.getMatcher(PatternMatcher.EXACT)));
388 }
389 }
390
391 return result;
392 }
393
394 private void onMissingDescriptor(File buildFile, File ivyFile, List<File> noDescriptor) {
395 switch (onMissingDescriptor) {
396 case OnMissingDescriptor.FAIL:
397 throw new BuildException("a module has no module descriptor and"
398 + " onMissingDescriptor=fail. Build file: " + buildFile
399 + ". Expected descriptor: " + ivyFile);
400 case OnMissingDescriptor.SKIP:
401 Message.debug("skipping " + buildFile + ": descriptor " + ivyFile
402 + " doesn't exist");
403 break;
404 case OnMissingDescriptor.WARN:
310405 Message.warn("a module has no module descriptor. " + "Build file: " + buildFile
311406 + ". Expected descriptor: " + ivyFile);
312 }
313 Message.verbose("no descriptor for "
314 + buildFile
315 + ": descriptor="
316 + ivyFile
317 + ": adding it at the "
318 + (OnMissingDescriptor.TAIL.equals(onMissingDescriptor) ? "tail" : "head"
319 + " of the path"));
320 Message.verbose("\t(change onMissingDescriptor if you want to take another action");
321 noDescriptor.add(buildFile);
322 }
323 }
324
325 private List convertModuleNamesToModuleDescriptors(Collection mds, Set moduleNames, String kind) {
326 List result = new ArrayList();
327 Set foundModuleNames = new HashSet();
328
329 for (Iterator it = mds.iterator(); it.hasNext();) {
330 ModuleDescriptor md = (ModuleDescriptor) it.next();
331 String name = md.getModuleRevisionId().getModuleId().getName();
332 if (moduleNames.contains(name)) {
333 foundModuleNames.add(name);
334 result.add(md);
335 }
336 }
337
338 if (foundModuleNames.size() < moduleNames.size()) {
339 Set missingModules = new HashSet(moduleNames);
340 missingModules.removeAll(foundModuleNames);
341
342 StringBuffer missingNames = new StringBuffer();
343 String sep = "";
344 for (Iterator it = missingModules.iterator(); it.hasNext();) {
345 missingNames.append(sep);
346 missingNames.append(it.next());
347 sep = ", ";
348 }
349
407 // fall through
408 default:
409 Message.verbose(String.format("no descriptor for %s: descriptor=%s: adding it at the %s of the path",
410 buildFile, ivyFile, (OnMissingDescriptor.TAIL.equals(onMissingDescriptor) ? "tail" : "head")));
411 Message.verbose("\t(change onMissingDescriptor if you want to take another action");
412 noDescriptor.add(buildFile);
413 break;
414 }
415 }
416
417 private List<ModuleDescriptor> findModuleDescriptors(
418 Collection<ModuleDescriptor> mds, Set<MapMatcher> matchers, String kind) {
419 List<ModuleDescriptor> result = new ArrayList<>();
420 Set<MapMatcher> missingMatchers = new HashSet<>(matchers);
421
422 for (ModuleDescriptor md : mds) {
423 Map<String, String> attributes = new HashMap<>();
424 attributes.putAll(md.getAttributes());
425 attributes.put("resource", md.getResource().getName());
426
427 for (MapMatcher matcher : matchers) {
428 if (matcher.matches(attributes)) {
429 missingMatchers.remove(matcher);
430 result.add(md);
431 }
432 }
433 }
434
435 if (!missingMatchers.isEmpty()) {
350436 throw new BuildException("unable to find " + kind + " module(s) "
351 + missingNames.toString() + " in build fileset");
437 + extractModuleNames(missingMatchers) + " in build fileset");
352438 }
353439
354440 return result;
355441 }
356442
443 private String extractModuleNames(Set<MapMatcher> matchers) {
444 StringBuilder result = new StringBuilder();
445
446 String sep = "";
447 for (MapMatcher matcher : matchers) {
448 result.append(sep);
449
450 Map<String, String> attributes = matcher.getAttributes();
451 String organisation = attributes.get(IvyPatternHelper.ORGANISATION_KEY);
452 if (organisation != null && !PatternMatcher.ANY_EXPRESSION.equals(organisation)) {
453 result.append(organisation);
454 result.append('#');
455 }
456 result.append(attributes.get(IvyPatternHelper.MODULE_KEY));
457 sep = ", ";
458 }
459
460 return result.toString();
461 }
462
357463 /**
358 * Returns a collection of ModuleDescriptors that are conatined in the input collection of
464 * Returns a collection of ModuleDescriptors that are contained in the input collection of
359465 * ModuleDescriptors and upon which the root module depends
360 *
466 *
361467 * @param mds
362468 * input collection of ModuleDescriptors
363 * @param rootmd
469 * @param rootmds
364470 * root module
365471 * @return filtered list of modules
366472 */
367 private Collection filterModulesFromRoot(Collection mds, List rootmds) {
368 // Make a map of ModuleId objects -> ModuleDescriptors
369 Map moduleIdMap = new HashMap();
370 for (Iterator iter = mds.iterator(); iter.hasNext();) {
371 ModuleDescriptor md = ((ModuleDescriptor) iter.next());
473 private Collection<ModuleDescriptor> filterModulesFromRoot(Collection<ModuleDescriptor> mds,
474 List<ModuleDescriptor> rootmds) {
475 Map<ModuleId, ModuleDescriptor> moduleIdMap = new HashMap<>();
476 for (ModuleDescriptor md : mds) {
372477 moduleIdMap.put(md.getModuleRevisionId().getModuleId(), md);
373478 }
374479
375480 // recursively process the nodes
376 Set toKeep = new LinkedHashSet();
377
378 Iterator it = rootmds.iterator();
379 while (it.hasNext()) {
380 ModuleDescriptor rootmd = (ModuleDescriptor) it.next();
481 Set<ModuleDescriptor> toKeep = new LinkedHashSet<>();
482
483 for (ModuleDescriptor rootmd : rootmds) {
381484 processFilterNodeFromRoot(rootmd, toKeep, moduleIdMap);
382485 // With the excluderoot attribute set to true, take the rootmd out of the toKeep set.
383486 if (excludeRoot) {
390493 }
391494
392495 // just for logging
393 for (Iterator iter = toKeep.iterator(); iter.hasNext();) {
394 ModuleDescriptor md = ((ModuleDescriptor) iter.next());
496 for (ModuleDescriptor md : toKeep) {
395497 Message.verbose("Kept module " + md.getModuleRevisionId().getModuleId().getName());
396498 }
397499
402504 * Adds the current node to the toKeep collection and then processes the each of the direct
403505 * dependencies of this node that appear in the moduleIdMap (indicating that the dependency is
404506 * part of this BuildList)
405 *
507 *
406508 * @param node
407509 * the node to be processed
408510 * @param toKeep
410512 * @param moduleIdMap
411513 * reference mapping of moduleId to ModuleDescriptor that are part of the BuildList
412514 */
413 private void processFilterNodeFromRoot(ModuleDescriptor node, Set toKeep, Map moduleIdMap) {
515 private void processFilterNodeFromRoot(ModuleDescriptor node, Set<ModuleDescriptor> toKeep,
516 Map<ModuleId, ModuleDescriptor> moduleIdMap) {
414517 // toKeep.add(node);
415
416 DependencyDescriptor[] deps = node.getDependencies();
417 for (int i = 0; i < deps.length; i++) {
418 ModuleId id = deps[i].getDependencyId();
419 ModuleDescriptor md = (ModuleDescriptor) moduleIdMap.get(id);
518 for (DependencyDescriptor dep : node.getDependencies()) {
519 ModuleId id = dep.getDependencyId();
520 ModuleDescriptor md = moduleIdMap.get(id);
420521 // we test if this module id has a module descriptor, and if it isn't already in the
421522 // toKeep Set, in which there's probably a circular dependency
422523 if (md != null && !toKeep.contains(md)) {
429530 }
430531
431532 /**
432 * Returns a collection of ModuleDescriptors that are conatined in the input collection of
533 * Returns a collection of ModuleDescriptors that are contained in the input collection of
433534 * ModuleDescriptors which depends on the leaf module
434 *
535 *
435536 * @param mds
436537 * input collection of ModuleDescriptors
437 * @param leafmd
538 * @param leafmds
438539 * leaf module
439540 * @return filtered list of modules
440541 */
441 private Collection filterModulesFromLeaf(Collection mds, List leafmds) {
442 // Make a map of ModuleId objects -> ModuleDescriptors
443 Map moduleIdMap = new HashMap();
444 for (Iterator iter = mds.iterator(); iter.hasNext();) {
445 ModuleDescriptor md = ((ModuleDescriptor) iter.next());
542 private Collection<ModuleDescriptor> filterModulesFromLeaf(Collection<ModuleDescriptor> mds,
543 List<ModuleDescriptor> leafmds) {
544 Map<ModuleId, ModuleDescriptor> moduleIdMap = new HashMap<>();
545 for (ModuleDescriptor md : mds) {
446546 moduleIdMap.put(md.getModuleRevisionId().getModuleId(), md);
447547 }
448548
449549 // recursively process the nodes
450 Set toKeep = new LinkedHashSet();
451 Iterator it = leafmds.iterator();
452 while (it.hasNext()) {
453 ModuleDescriptor leafmd = (ModuleDescriptor) it.next();
550 Set<ModuleDescriptor> toKeep = new LinkedHashSet<>();
551 for (ModuleDescriptor leafmd : leafmds) {
454552 // With the excludeleaf attribute set to true, take the rootmd out of the toKeep set.
455553 if (excludeLeaf) {
456554 Message.verbose("Excluded module "
462560 }
463561
464562 // just for logging
465 for (Iterator iter = toKeep.iterator(); iter.hasNext();) {
466 ModuleDescriptor md = ((ModuleDescriptor) iter.next());
563 for (ModuleDescriptor md : toKeep) {
467564 Message.verbose("Kept module " + md.getModuleRevisionId().getModuleId().getName());
468565 }
469566
473570 /**
474571 * Search in the moduleIdMap modules depending on node, add them to the toKeep set and process
475572 * them recursively.
476 *
573 *
477574 * @param node
478575 * the node to be processed
479576 * @param toKeep
481578 * @param moduleIdMap
482579 * reference mapping of moduleId to ModuleDescriptor that are part of the BuildList
483580 */
484 private void processFilterNodeFromLeaf(ModuleDescriptor node, Set toKeep, Map moduleIdMap) {
485 for (Iterator iter = moduleIdMap.values().iterator(); iter.hasNext();) {
486 ModuleDescriptor md = (ModuleDescriptor) iter.next();
487 DependencyDescriptor[] deps = md.getDependencies();
488 for (int i = 0; i < deps.length; i++) {
489 ModuleId id = deps[i].getDependencyId();
490 if (node.getModuleRevisionId().getModuleId().equals(id) && !toKeep.contains(md)) {
581 private void processFilterNodeFromLeaf(ModuleDescriptor node, Set<ModuleDescriptor> toKeep,
582 Map<ModuleId, ModuleDescriptor> moduleIdMap) {
583 for (ModuleDescriptor md : moduleIdMap.values()) {
584 for (DependencyDescriptor dep : md.getDependencies()) {
585 if (node.getModuleRevisionId().getModuleId().equals(dep.getDependencyId())
586 && !toKeep.contains(md)) {
491587 toKeep.add(md);
492588 if (!getOnlydirectdep()) {
493589 processFilterNodeFromLeaf(md, toKeep, moduleIdMap);
532628 }
533629
534630 /**
631 * @return boolean
535632 * @deprecated use {@link #getOnMissingDescriptor()} instead.
536633 */
537634 @Deprecated
538635 public boolean isSkipbuildwithoutivy() {
539 return onMissingDescriptor == OnMissingDescriptor.SKIP;
636 return OnMissingDescriptor.SKIP.equals(onMissingDescriptor);
540637 }
541638
542639 /**
640 * @param skipBuildFilesWithoutIvy boolean
543641 * @deprecated use {@link #setOnMissingDescriptor(String)} instead.
544642 */
545643 @Deprecated
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.ant;
1818
19 import java.util.ArrayList;
1920 import java.util.List;
2021 import java.util.ListIterator;
22 import java.util.regex.Pattern;
2123
2224 import org.apache.ivy.Ivy;
2325 import org.apache.ivy.core.module.id.ModuleId;
3537 import org.apache.ivy.plugins.version.VersionMatcher;
3638 import org.apache.tools.ant.BuildException;
3739
40 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
41
3842 /**
3943 * Look for the latest module in the repository matching the given criteria, and sets a set of
4044 * properties according to what was found.
148152 if (branch == null) {
149153 branch = settings.getDefaultBranch(new ModuleId(organisation, module));
150154 }
151 if (revision == null || revision.length() == 0) {
155 if (isNullOrEmpty(revision)) {
152156 revision = "latest.integration";
153157 } else if (!revision.endsWith("+")) {
154 revision = revision + "+";
155 }
156 if (!prefix.endsWith(".") && prefix.length() > 0) {
157 prefix = prefix + ".";
158 revision += "+";
159 }
160 if (!prefix.endsWith(".") && !prefix.isEmpty()) {
161 prefix += ".";
158162 }
159163
160164 SearchEngine searcher = new SearchEngine(settings);
168172 if (expression.equals(organisation) || expression.equals(module)
169173 || expression.equals(branch)) {
170174 return exact.getMatcher(expression);
175 } else {
176 return regexp.getMatcher(expression);
171177 }
172 return regexp.getMatcher(expression);
173178 }
174179
175180 public String getName() {
176181 return "buildnumber-matcher";
177182 }
178183 };
184
185 String revisionPattern = ".*";
186 if (revision.endsWith("+")) {
187 revisionPattern = Pattern.quote(revision.substring(0, revision.length() - 1)) + ".*";
188 }
189
190 ModuleRevisionId mrid = ModuleRevisionId.newInstance(organisation, module, branch,
191 revisionPattern);
179192 ModuleRevisionId[] revisions;
180193 if (resolver == null) {
181 revisions = searcher.listModules(
182 ModuleRevisionId.newInstance(organisation, module, branch, ".*"), patternMatcher);
194 revisions = searcher.listModules(mrid, patternMatcher);
183195 } else {
184196 DependencyResolver depResolver = settings.getResolver(resolver);
185197 if (depResolver == null) {
186198 throw new BuildException("Unknown resolver: " + resolver);
187199 }
188 revisions = searcher.listModules(depResolver,
189 ModuleRevisionId.newInstance(organisation, module, branch, ".*"), patternMatcher);
190 }
191
192 ArtifactInfo[] infos = new ArtifactInfo[revisions.length];
193 for (int i = 0; i < revisions.length; i++) {
194 infos[i] = new ResolvedModuleRevisionArtifactInfo(revisions[i]);
200 revisions = searcher.listModules(depResolver, mrid, patternMatcher);
201 }
202
203 List<ArtifactInfo> infos = new ArrayList<>(revisions.length);
204 for (ModuleRevisionId rev : revisions) {
205 infos.add(new ResolvedModuleRevisionArtifactInfo(rev));
195206 }
196207
197208 VersionMatcher matcher = settings.getVersionMatcher();
198209 LatestStrategy latestStrategy = settings.getLatestStrategy("latest-revision");
199 List sorted = latestStrategy.sort(infos);
210 List<ArtifactInfo> sorted = latestStrategy.sort(infos.toArray(new ArtifactInfo[revisions.length]));
200211
201212 ModuleRevisionId askedMrid = ModuleRevisionId.newInstance(organisation, module, branch,
202213 revision);
203214
204215 String foundRevision = null;
205 for (ListIterator iter = sorted.listIterator(sorted.size()); iter.hasPrevious();) {
216 ListIterator<ArtifactInfo> iter = sorted.listIterator(sorted.size());
217 while (iter.hasPrevious()) {
206218 ResolvedModuleRevisionArtifactInfo info = (ResolvedModuleRevisionArtifactInfo) iter
207219 .previous();
208220
301313 while (endNumberIndex >= 0 && !Character.isDigit(str.charAt(endNumberIndex))) {
302314 endNumberIndex--;
303315 }
304 int startNumberIndex = endNumberIndex == -1 ? -1 : endNumberIndex - 1;
316 int startNumberIndex = (endNumberIndex == -1) ? -1 : endNumberIndex - 1;
305317 while (startNumberIndex >= 0 && Character.isDigit(str.charAt(startNumberIndex))) {
306318 startNumberIndex--;
307319 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 import org.apache.tools.ant.Project;
2929 import org.apache.tools.ant.types.FileSet;
3030 import org.apache.tools.ant.types.PatternSet.NameEntry;
31 import org.apache.tools.ant.types.Resource;
3132
3233 /**
33 * Creates an ant fileset consisting in all artifacts found during a resolve. Note that this task is
34 * not compatible with the useOrigin mode.
34 * Creates an ant fileset consisting in all artifacts found during a resolve. Note that this task
35 * is not compatible with the useOrigin mode.
3536 */
3637 public class IvyCacheFileset extends IvyCacheTask {
3738 private String setid;
4849 if (useOrigin) {
4950 throw new UnsupportedOperationException(
5051 "the cachefileset task does not support the useOrigin mode, since filesets "
51 + "require to have only one root directory. Please use the the cachepath "
52 + "task instead");
52 + "require to have only one root directory. Please use the the "
53 + "cachepath task instead");
5354 }
5455 }
5556
5960 throw new BuildException("setid is required in ivy cachefileset");
6061 }
6162 try {
62 List paths = getArtifactReports();
63 File base = null;
64 for (Iterator iter = paths.iterator(); iter.hasNext();) {
65 ArtifactDownloadReport a = (ArtifactDownloadReport) iter.next();
66 if (a.getLocalFile() != null) {
67 base = getBaseDir(base, a.getLocalFile());
63 final List<ArtifactDownloadReport> artifactDownloadReports = getArtifactReports();
64 if (artifactDownloadReports.isEmpty()) {
65 // generate an empty fileset
66 final FileSet emptyFileSet = new EmptyFileSet();
67 emptyFileSet.setProject(getProject());
68 getProject().addReference(setid, emptyFileSet);
69 return;
70 }
71 // find a common base dir of the resolved artifacts
72 final File baseDir = this.requireCommonBaseDir(artifactDownloadReports);
73 final FileSet fileset = new FileSet();
74 fileset.setDir(baseDir);
75 fileset.setProject(getProject());
76 // enroll each of the artifact files into the fileset
77 for (final ArtifactDownloadReport artifactDownloadReport : artifactDownloadReports) {
78 if (artifactDownloadReport.getLocalFile() == null) {
79 continue;
6880 }
69 }
70
71 FileSet fileset;
72 if (base == null) {
73 fileset = new EmptyFileSet();
74 } else {
75 fileset = new FileSet();
76 fileset.setDir(base);
77 for (Iterator iter = paths.iterator(); iter.hasNext();) {
78 ArtifactDownloadReport a = (ArtifactDownloadReport) iter.next();
79 if (a.getLocalFile() != null) {
80 NameEntry ne = fileset.createInclude();
81 ne.setName(getPath(base, a.getLocalFile()));
82 }
83 }
84 }
85
86 fileset.setProject(getProject());
81 final NameEntry ne = fileset.createInclude();
82 ne.setName(getPath(baseDir, artifactDownloadReport.getLocalFile()));
83 }
8784 getProject().addReference(setid, fileset);
8885 } catch (Exception ex) {
8986 throw new BuildException("impossible to build ivy cache fileset: " + ex, ex);
9188 }
9289
9390 /**
91 * Returns a common base directory, determined from the
92 * {@link ArtifactDownloadReport#getLocalFile() local files} of the passed
93 * <code>artifactDownloadReports</code>. If no common base directory can be determined, this
94 * method throws a {@link BuildException}
95 *
96 * @param artifactDownloadReports The artifact download reports for which the common base
97 * directory of the artifacts has to be determined
98 * @return File
99 */
100 File requireCommonBaseDir(final List<ArtifactDownloadReport> artifactDownloadReports) {
101 File base = null;
102 for (final ArtifactDownloadReport artifactDownloadReport : artifactDownloadReports) {
103 if (artifactDownloadReport.getLocalFile() == null) {
104 continue;
105 }
106 if (base == null) {
107 // use the parent dir of the artifact as the base
108 base = artifactDownloadReport.getLocalFile().getParentFile().getAbsoluteFile();
109 } else {
110 // try and find a common base directory between the current base
111 // directory and the artifact's file
112 base = getBaseDir(base, artifactDownloadReport.getLocalFile());
113 if (base == null) {
114 // fail fast - we couldn't determine a common base directory, throw an error
115 throw new BuildException("Cannot find a common base directory, from resolved "
116 + "artifacts, for generating a cache fileset");
117 }
118 }
119 }
120 if (base == null) {
121 // finally, we couldn't determine a common base directory, throw an error
122 throw new BuildException("Cannot find a common base directory, from resolved "
123 + "artifacts, for generating a cache fileset");
124 }
125 return base;
126 }
127
128 /**
94129 * Returns the path of the file relative to the given base directory.
95 *
130 *
96131 * @param base
97132 * the parent directory to which the file must be evaluated.
98133 * @param file
107142 // checks if the basePath ends with the file separator (which can for instance
108143 // happen if the basePath is the root on unix)
109144 if (!absoluteBasePath.endsWith(File.separator)) {
110 beginIndex++; // skip the seperator char as well
145 beginIndex++; // skip the separator char as well
111146 }
112147
113148 return file.getAbsolutePath().substring(beginIndex);
114149 }
115150
116151 /**
117 * Returns the common base directory between a current base directory and a given file.
152 * Returns the common base directory between the passed <code>file1</code> and
153 * <code>file2</code>.
118154 * <p>
119 * The returned base directory must be a parent of both the current base and the given file.
155 * The returned base directory will be a parent of both the <code>file1</code> and
156 * <code>file2</code> or it will be <code>null</code>.
120157 * </p>
121 *
122 * @param base
123 * the current base directory, may be null.
124 * @param file
125 * the file for which the new base directory should be returned.
126 * @return the common base directory between a current base directory and a given file.
127 */
128 File getBaseDir(File base, File file) {
129 if (base == null) {
130 return file.getParentFile().getAbsoluteFile();
131 } else {
132 Iterator bases = getParents(base).iterator();
133 Iterator fileParents = getParents(file.getAbsoluteFile()).iterator();
134 File result = null;
135 while (bases.hasNext() && fileParents.hasNext()) {
136 File next = (File) bases.next();
137 if (next.equals(fileParents.next())) {
138 result = next;
139 } else {
140 break;
141 }
142 }
143 return result;
144 }
158 *
159 * @param file1
160 * One of the files, for which the common base directory is being sought, may be null.
161 * @param file2
162 * The other file for which the common base directory should be returned, may be null.
163 * @return the common base directory between a <code>file1</code> and <code>file2</code>.
164 * Returns null if no common base directory could be determined or if either
165 * <code>file1</code> or <code>file2</code> is null
166 */
167 File getBaseDir(final File file1, final File file2) {
168 if (file1 == null || file2 == null) {
169 return null;
170 }
171 final Iterator<File> file1Parents = getParents(file1).iterator();
172 final Iterator<File> file2Parents = getParents(file2.getAbsoluteFile()).iterator();
173 File result = null;
174 while (file1Parents.hasNext() && file2Parents.hasNext()) {
175 File next = file1Parents.next();
176 if (next.equals(file2Parents.next())) {
177 result = next;
178 } else {
179 break;
180 }
181 }
182 return result;
145183 }
146184
147185 /**
148186 * @return a list of files, starting with the root and ending with the file itself
149187 */
150 private LinkedList/* <File> */getParents(File file) {
151 LinkedList r = new LinkedList();
188 private LinkedList<File> getParents(File file) {
189 LinkedList<File> r = new LinkedList<>();
152190 while (file != null) {
153191 r.addFirst(file);
154192 file = file.getParentFile();
160198
161199 private DirectoryScanner ds = new EmptyDirectoryScanner();
162200
163 public Iterator iterator() {
164 return new EmptyIterator();
201 public Iterator<Resource> iterator() {
202 return new EmptyIterator<>();
165203 }
166204
167205 public Object clone() {
177215 }
178216 }
179217
180 private static class EmptyIterator implements Iterator {
218 private static class EmptyIterator<T> implements Iterator<T> {
181219
182220 public boolean hasNext() {
183221 return false;
184222 }
185223
186 public Object next() {
224 public T next() {
187225 throw new NoSuchElementException("EmptyFileSet Iterator");
188226 }
189227
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.ant;
1818
1919 import java.io.File;
20 import java.util.Iterator;
2120 import java.util.List;
2221
2322 import org.apache.ivy.core.report.ArtifactDownloadReport;
5251
5352 /**
5453 * @deprecated use setPathid instead
55 * @param id
54 * @param id String
5655 */
5756 @Deprecated
5857 public void setId(String id) {
6261 public void doExecute() throws BuildException {
6362 prepareAndCheck();
6463 if (pathid == null) {
65 if (id != null) {
66 pathid = id;
67 log("ID IS DEPRECATED, PLEASE USE PATHID INSTEAD", Project.MSG_WARN);
68 } else {
64 if (id == null) {
6965 throw new BuildException("pathid is required in ivy classpath");
7066 }
67 pathid = id;
68 log("ID IS DEPRECATED, PLEASE USE PATHID INSTEAD", Project.MSG_WARN);
7169 }
7270 try {
7371 Path path = new Path(getProject());
7472 getProject().addReference(pathid, path);
75 for (Iterator iter = getArtifactReports().iterator(); iter.hasNext();) {
76 ArtifactDownloadReport a = (ArtifactDownloadReport) iter.next();
77 File f = a.getLocalFile();
78 if (a.getUnpackedLocalFile() != null) {
79 f = a.getUnpackedLocalFile();
73 for (ArtifactDownloadReport adr : getArtifactReports()) {
74 File f = adr.getLocalFile();
75 if (adr.getUnpackedLocalFile() != null) {
76 f = adr.getUnpackedLocalFile();
8077 }
8178 addToPath(path, f);
8279 }
9794 return;
9895 }
9996 BundleInfo bundleInfo = ManifestParser.parseManifest(manifest);
100 List/* <String> */cp = bundleInfo.getClasspath();
97 List<String> cp = bundleInfo.getClasspath();
10198 if (cp == null) {
10299 path.createPathElement().setLocation(f);
103100 return;
104101 }
105 for (int i = 0; i < cp.size(); i++) {
106 String p = (String) cp.get(i);
102 for (String p : cp) {
107103 if (p.equals(".")) {
108104 path.createPathElement().setLocation(f);
109105 } else {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.ant;
1818
1919 import java.io.File;
20 import java.io.IOException;
2120 import java.text.ParseException;
2221 import java.util.ArrayList;
2322 import java.util.Arrays;
2423 import java.util.Collection;
2524 import java.util.LinkedHashSet;
2625 import java.util.List;
27 import java.util.Set;
2826
2927 import org.apache.ivy.core.cache.ResolutionCacheManager;
3028 import org.apache.ivy.core.module.id.ModuleRevisionId;
3634 import org.apache.ivy.util.Message;
3735 import org.apache.tools.ant.BuildException;
3836
37 import static org.apache.ivy.util.StringUtils.splitToArray;
38
3939 /**
40 * Base class for the cache path related classes: cachepath and cachefileset. Most of the behviour
40 * Base class for the cache path related classes: cachepath and cachefileset. Most of the behaviour
4141 * is common to the two, since only the produced element differs.
4242 */
4343 public abstract class IvyCacheTask extends IvyPostResolveTask {
4444
4545 protected List<ArtifactDownloadReport> getArtifactReports() throws BuildException,
46 ParseException, IOException {
47 Collection<ArtifactDownloadReport> artifacts = getAllArtifactReports();
48 List<ArtifactDownloadReport> ret = new ArrayList<ArtifactDownloadReport>();
49 for (ArtifactDownloadReport artifactReport : artifacts) {
46 ParseException {
47 List<ArtifactDownloadReport> ret = new ArrayList<>();
48 for (ArtifactDownloadReport artifactReport : getAllArtifactReports()) {
5049 if (getArtifactFilter().accept(artifactReport.getArtifact())) {
5150 ret.add(artifactReport);
5251 }
5554 return ret;
5655 }
5756
58 private Collection<ArtifactDownloadReport> getAllArtifactReports() throws ParseException,
59 IOException {
60 String[] confs = splitConfs(getConf());
61 Collection<ArtifactDownloadReport> all = new LinkedHashSet<ArtifactDownloadReport>();
57 private Collection<ArtifactDownloadReport> getAllArtifactReports() throws ParseException {
58 String[] confs = splitToArray(getConf());
59 Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
6260
6361 ResolveReport report = getResolvedReport();
6462 if (report != null) {
6563 Message.debug("using internal report instance to get artifacts list");
66 for (int i = 0; i < confs.length; i++) {
64 for (String conf : confs) {
6765 ConfigurationResolveReport configurationReport = report
68 .getConfigurationReport(confs[i]);
66 .getConfigurationReport(conf);
6967 if (configurationReport == null) {
70 throw new BuildException("bad confs provided: " + confs[i]
68 throw new BuildException("bad confs provided: " + conf
7169 + " not found among " + Arrays.asList(report.getConfigurations()));
7270 }
73 Set<ModuleRevisionId> revisions = configurationReport.getModuleRevisionIds();
74 for (ModuleRevisionId revId : revisions) {
75 ArtifactDownloadReport[] aReports = configurationReport
76 .getDownloadReports(revId);
77 all.addAll(Arrays.asList(aReports));
71 for (ModuleRevisionId revId : configurationReport.getModuleRevisionIds()) {
72 all.addAll(Arrays.asList(configurationReport.getDownloadReports(revId)));
7873 }
7974 }
8075 } else {
8681 if (resolvedId == null) {
8782 resolvedId = ResolveOptions.getDefaultResolveId(getResolvedModuleId());
8883 }
89 for (int i = 0; i < confs.length; i++) {
84 for (String conf : confs) {
9085 File reportFile = cacheMgr.getConfigurationResolveReportInCache(resolvedId,
91 confs[i]);
86 conf);
9287 parser.parse(reportFile);
9388
94 ArtifactDownloadReport[] aReports = parser.getArtifactReports();
95 all.addAll(Arrays.asList(aReports));
89 all.addAll(Arrays.asList(parser.getArtifactReports()));
9690 }
9791 }
9892 return all;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3737 public class IvyCheck extends IvyTask {
3838 private File file = null;
3939
40 private List filesets = new ArrayList();
40 private final List<FileSet> filesets = new ArrayList<>();
4141
4242 private String resolvername;
4343
5151
5252 /**
5353 * Adds a set of files to check.
54 *
54 *
5555 * @param set
5656 * a set of files to check
5757 */
7575 Message.verbose("checked " + file + ": OK");
7676 }
7777 }
78 for (int i = 0; i < filesets.size(); i++) {
79 FileSet fs = (FileSet) filesets.get(i);
78 for (FileSet fs : filesets) {
8079 DirectoryScanner ds = fs.getDirectoryScanner(getProject());
8180
8281 File fromDir = fs.getDir(getProject());
8382
84 String[] srcFiles = ds.getIncludedFiles();
85 for (int j = 0; j < srcFiles.length; j++) {
86 File file = new File(fromDir, srcFiles[j]);
83 for (String srcFile : ds.getIncludedFiles()) {
84 File file = new File(fromDir, srcFile);
8785 if (ivy.check(file.toURI().toURL(), resolvername)) {
8886 Message.verbose("checked " + file + ": OK");
8987 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3939 /**
4040 * Sets the name of the repository cache to clean, '*' for all caches, 'NONE' for no repository
4141 * cache cleaning at all.
42 *
42 *
4343 * @param cache
4444 * the name of the cache to clean. Must not be <code>null</code>.
4545 */
5252 }
5353
5454 /**
55 * Sets weither the resolution cache should be cleaned or not.
56 *
55 * Sets whether the resolution cache should be cleaned or not.
56 *
5757 * @param resolution
5858 * <code>true</code> if the resolution cache should be cleaned, <code>false</code>
5959 * otherwise.
6868 settings.getResolutionCacheManager().clean();
6969 }
7070 if (ALL.equals(getCache())) {
71 RepositoryCacheManager[] caches = settings.getRepositoryCacheManagers();
72 for (int i = 0; i < caches.length; i++) {
73 caches[i].clean();
71 for (RepositoryCacheManager cache : settings.getRepositoryCacheManagers()) {
72 cache.clean();
7473 }
7574 } else if (!NONE.equals(getCache())) {
7675 RepositoryCacheManager cache = settings.getRepositoryCacheManager(getCache());
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4747 */
4848 public static final String OVERRIDE_NOT_ALLOWED = "notallowed";
4949
50 private static final Collection OVERRIDE_VALUES = Arrays.asList(new String[] {OVERRIDE_TRUE,
51 OVERRIDE_FALSE, OVERRIDE_NOT_ALLOWED});
50 private static final Collection<String> OVERRIDE_VALUES = Arrays.asList(OVERRIDE_TRUE,
51 OVERRIDE_FALSE, OVERRIDE_NOT_ALLOWED);
5252
5353 private String override = OVERRIDE_NOT_ALLOWED;
5454
129129 settings.setPasswd(passwd);
130130 }
131131
132 public void addConfiguredWorkspaceResolver(AntWorkspaceResolver resolver) {
133 settings.addConfiguredWorkspaceResolver(resolver);
134 }
135
136 @Override
132137 public void execute() throws BuildException {
133138 String settingsId = settings.getId();
134139 Object otherRef = getProject().getReference(settingsId);
135140
136 if ((otherRef != null) && OVERRIDE_NOT_ALLOWED.equals(override)) {
141 if (otherRef != null && OVERRIDE_NOT_ALLOWED.equals(override)) {
137142 throw new BuildException(
138143 "Overriding a previous definition of ivy:settings with the id '" + settingsId
139144 + "' is not allowed when using override='" + OVERRIDE_NOT_ALLOWED
140145 + "'.");
141146 }
142147
143 if ((otherRef != null) && OVERRIDE_FALSE.equals(override)) {
148 if (otherRef != null && OVERRIDE_FALSE.equals(override)) {
144149 verbose("A settings definition is already available for " + settingsId + ": skipping");
145150 return;
146151 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import org.apache.ivy.plugins.conflict.ConflictManager;
2323 import org.apache.ivy.plugins.conflict.FixedConflictManager;
2424 import org.apache.ivy.plugins.matcher.PatternMatcher;
25
26 import static org.apache.ivy.util.StringUtils.splitToArray;
2527
2628 public class IvyConflict {
2729
5658 }
5759
5860 void addConflict(DefaultModuleDescriptor md, IvySettings settings) {
59 String matcherName = matcher == null ? PatternMatcher.EXACT : matcher;
60 String orgPattern = org == null ? PatternMatcher.ANY_EXPRESSION : org;
61 String modulePattern = module == null ? PatternMatcher.ANY_EXPRESSION : module;
61 String matcherName = (matcher == null) ? PatternMatcher.EXACT : matcher;
62 String orgPattern = (org == null) ? PatternMatcher.ANY_EXPRESSION : org;
63 String modulePattern = (module == null) ? PatternMatcher.ANY_EXPRESSION : module;
6264 ConflictManager cm = null;
6365 if (rev != null) {
64 String[] revs = rev.split(",");
65 for (int i = 0; i < revs.length; i++) {
66 revs[i] = revs[i].trim();
67 }
68 cm = new FixedConflictManager(revs);
66 cm = new FixedConflictManager(splitToArray(rev));
6967 } else if (manager != null) {
7068 cm = settings.getConflictManager(manager);
7169 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3434 import org.apache.tools.ant.taskdefs.Echo;
3535 import org.apache.tools.ant.taskdefs.Input;
3636 import org.apache.tools.ant.taskdefs.Property;
37
38 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
39 import static org.apache.ivy.util.StringUtils.splitToArray;
3740
3841 /**
3942 * Trigger the delivery of a module, which may consist in a recursive delivery of dependencies and
140143
141144 public void deliverDependency(ModuleRevisionId depMrid, String version, String status,
142145 String depStatus) {
146 if (isNullOrEmpty(deliverTarget)) {
147 return;
148 }
143149 // call deliver target if any
144 if (deliverTarget != null && deliverTarget.trim().length() > 0) {
145
146 CallTarget ct = (CallTarget) getProject().createTask("antcall");
147 ct.setOwningTarget(getOwningTarget());
148 ct.init();
149 ct.setTarget(deliverTarget);
150 ct.setInheritAll(true);
151 ct.setInheritRefs(true);
152 Property param = ct.createParam();
153 param.setName("dependency.name");
154 param.setValue(depMrid.getName());
155 param = ct.createParam();
156 param.setName("dependency.published.status");
157 param.setValue(status);
158 param = ct.createParam();
159 param.setName("dependency.published.version");
160 param.setValue(version);
161 param = ct.createParam();
162 param.setName("dependency.version");
163 param.setValue(depMrid.getRevision());
164 param = ct.createParam();
165 param.setName("dependency.status");
166 param.setValue(depStatus == null ? "null" : depStatus);
167
168 ct.perform();
169
170 String deliveredProperty = depMrid.getName() + "." + depMrid.getRevision()
171 + ".delivered";
172 getProject().setProperty(deliveredProperty, "true");
173 appendDeliveryList(deliveredProperty + " = true");
174
175 getProject().setProperty("recursive." + depMrid.getName() + ".delivered", "true");
176 appendDeliveryList("recursive." + depMrid.getName() + ".delivered" + " = true");
177 }
150 CallTarget ct = (CallTarget) getProject().createTask("antcall");
151 ct.setOwningTarget(getOwningTarget());
152 ct.init();
153 ct.setTarget(deliverTarget);
154 ct.setInheritAll(true);
155 ct.setInheritRefs(true);
156 Property param = ct.createParam();
157 param.setName("dependency.name");
158 param.setValue(depMrid.getName());
159 param = ct.createParam();
160 param.setName("dependency.published.status");
161 param.setValue(status);
162 param = ct.createParam();
163 param.setName("dependency.published.version");
164 param.setValue(version);
165 param = ct.createParam();
166 param.setName("dependency.version");
167 param.setValue(depMrid.getRevision());
168 param = ct.createParam();
169 param.setName("dependency.status");
170 param.setValue(depStatus == null ? "null" : depStatus);
171
172 ct.perform();
173
174 String deliveredProperty = depMrid.getName() + "." + depMrid.getRevision()
175 + ".delivered";
176 getProject().setProperty(deliveredProperty, "true");
177 appendDeliveryList(deliveredProperty + " = true");
178
179 getProject().setProperty("recursive." + depMrid.getName() + ".delivered", "true");
180 appendDeliveryList("recursive." + depMrid.getName() + ".delivered" + " = true");
178181 }
179182
180183 }
358361 if (resolveId == null) {
359362 if (organisation == null) {
360363 throw new BuildException("no organisation provided for ivy deliver task: "
361 + "It can either be set explicitely via the attribute 'organisation' "
364 + "It can either be set explicitly via the attribute 'organisation' "
362365 + "or via 'ivy.organisation' property or a prior call to <resolve/>");
363366 }
364367 if (module == null) {
365368 throw new BuildException("no module name provided for ivy deliver task: "
366 + "It can either be set explicitely via the attribute 'module' "
369 + "It can either be set explicitly via the attribute 'module' "
367370 + "or via 'ivy.module' property or a prior call to <resolve/>");
368371 }
369372 }
402405 loadDeliveryList();
403406
404407 PublishingDependencyRevisionResolver drResolver;
405 if (deliverTarget != null && deliverTarget.trim().length() > 0) {
408 if (isNullOrEmpty(deliverTarget)) {
409 drResolver = new DefaultPublishingDRResolver();
410 } else {
406411 drResolver = new DeliverDRResolver();
407 } else {
408 drResolver = new DefaultPublishingDRResolver();
409412 }
410413
411414 DeliverOptions options = new DeliverOptions(status, pubdate, drResolver,
412 doValidate(settings), replacedynamicrev, splitConfs(conf))
415 doValidate(settings), replacedynamicrev, splitToArray(conf))
413416 .setResolveId(resolveId).setReplaceForcedRevisions(isReplaceForcedRev())
414417 .setGenerateRevConstraint(generateRevConstraint).setMerge(merge)
415418 .setPubBranch(pubBranch);
419422 ivy.deliver(mrid, pubRevision, deliverpattern, options);
420423 }
421424 } catch (Exception e) {
422 throw new BuildException("impossible to deliver " + mrid == null ? resolveId : mrid
425 throw new BuildException("impossible to deliver " + (mrid == null ? resolveId : mrid)
423426 + ": " + e, e);
424427 } finally {
425428 if (isLeading) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.ant;
1818
1919 import java.util.ArrayList;
20 import java.util.Iterator;
2120 import java.util.List;
2221
2322 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
3130
3231 public class IvyDependency {
3332
34 private List/* <IvyDependencyConf> */confs = new ArrayList();
33 private List<IvyDependencyConf> confs = new ArrayList<>();
3534
36 private List/* <IvyDependencyArtifact> */artifacts = new ArrayList();
35 private List<IvyDependencyArtifact> artifacts = new ArrayList<>();
3736
38 private List/* <IvyDependencyExclude> */excludes = new ArrayList();
37 private List<IvyDependencyExclude> excludes = new ArrayList<>();
3938
40 private List/* <IvyDependencyIncludes> */includes = new ArrayList();
39 private List<IvyDependencyInclude> includes = new ArrayList<>();
4140
4241 private String org;
4342
160159 dd.addDependencyConfiguration(masterConf, "*");
161160 }
162161
163 Iterator itConfs = confs.iterator();
164 while (itConfs.hasNext()) {
165 IvyDependencyConf c = (IvyDependencyConf) itConfs.next();
162 for (IvyDependencyConf c : confs) {
166163 c.addConf(dd, masterConf);
167164 }
168165
169 Iterator itArtifacts = artifacts.iterator();
170 while (itArtifacts.hasNext()) {
171 IvyDependencyArtifact artifact = (IvyDependencyArtifact) itArtifacts.next();
166 for (IvyDependencyArtifact artifact : artifacts) {
172167 artifact.addArtifact(dd, masterConf);
173168 }
174169
175 Iterator itExcludes = excludes.iterator();
176 while (itExcludes.hasNext()) {
177 IvyDependencyExclude exclude = (IvyDependencyExclude) itExcludes.next();
170 for (IvyDependencyExclude exclude : excludes) {
178171 DefaultExcludeRule rule = exclude.asRule(settings);
179172 dd.addExcludeRule(masterConf, rule);
180173 }
181174
182 Iterator itIncludes = includes.iterator();
183 while (itIncludes.hasNext()) {
184 IvyDependencyInclude include = (IvyDependencyInclude) itIncludes.next();
175 for (IvyDependencyInclude include : includes) {
185176 DefaultIncludeRule rule = include.asRule(settings);
186177 dd.addIncludeRule(masterConf, rule);
187178 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.ant;
1818
1919 import java.util.ArrayList;
20 import java.util.Iterator;
2120 import java.util.List;
2221
2322 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
2423
24 import static org.apache.ivy.util.StringUtils.splitToArray;
25
2526 public class IvyDependencyConf {
2627
27 private List/* <IvyDependencyConfMapped> */mappeds = new ArrayList();
28 private final List<IvyDependencyConfMapped> mappeds = new ArrayList<>();
2829
2930 public static class IvyDependencyConfMapped {
3031 private String name;
4950
5051 void addConf(DefaultDependencyDescriptor dd, String masterConf) {
5152 if (mapped != null) {
52 String[] mappeds = mapped.split(",");
53 for (int i = 0; i < mappeds.length; i++) {
54 dd.addDependencyConfiguration(masterConf, mappeds[i].trim());
53 for (String map : splitToArray(mapped)) {
54 dd.addDependencyConfiguration(masterConf, map);
5555 }
5656 }
57 Iterator itMappeds = mappeds.iterator();
58 while (itMappeds.hasNext()) {
59 IvyDependencyConfMapped m = (IvyDependencyConfMapped) itMappeds.next();
57 for (IvyDependencyConfMapped m : mappeds) {
6058 dd.addDependencyConfiguration(masterConf, m.name);
6159 }
6260 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6161 }
6262
6363 DefaultExcludeRule asRule(IvySettings settings) {
64 String matcherName = matcher == null ? PatternMatcher.EXACT : matcher;
65 String orgPattern = org == null ? PatternMatcher.ANY_EXPRESSION : org;
66 String modulePattern = module == null ? PatternMatcher.ANY_EXPRESSION : module;
67 String namePattern = name == null ? PatternMatcher.ANY_EXPRESSION : name;
68 String typePattern = type == null ? PatternMatcher.ANY_EXPRESSION : type;
69 String extPattern = ext == null ? typePattern : ext;
64 String matcherName = (matcher == null) ? PatternMatcher.EXACT : matcher;
65 String orgPattern = (org == null) ? PatternMatcher.ANY_EXPRESSION : org;
66 String modulePattern = (module == null) ? PatternMatcher.ANY_EXPRESSION : module;
67 String namePattern = (name == null) ? PatternMatcher.ANY_EXPRESSION : name;
68 String typePattern = (type == null) ? PatternMatcher.ANY_EXPRESSION : type;
69 String extPattern = (ext == null) ? typePattern : ext;
7070 ArtifactId aid = new ArtifactId(new ModuleId(orgPattern, modulePattern), namePattern,
7171 typePattern, extPattern);
7272 return new DefaultExcludeRule(aid, settings.getMatcher(matcherName), null);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.HashMap;
21 import java.util.Iterator;
21 import java.util.HashSet;
2222 import java.util.List;
2323 import java.util.Map;
24 import java.util.Set;
2425
2526 import org.apache.ivy.core.module.id.ModuleRevisionId;
2627 import org.apache.ivy.core.report.ResolveReport;
3132
3233 public class IvyDependencyTree extends IvyPostResolveTask {
3334
34 private Map/* <ModuleRevisionId, List<IvyNode>> */dependencies = new HashMap/*
35 * <ModuleRevisionId,
36 * List<IvyNode>>
37 */();
35 private final Map<ModuleRevisionId, List<IvyNode>> dependencies = new HashMap<>();
3836
3937 private boolean showEvicted = false;
4038
4139 public void doExecute() throws BuildException {
4240 prepareAndCheck();
4341 ResolveReport report = getResolvedReport();
42 if (report == null) {
43 throw new BuildException("No resolution report was available to run the post-resolve task. Make sure resolve was done before this task");
44 }
4445 log("Dependency tree for " + report.getResolveId());
4546 ModuleRevisionId mrid = report.getModuleDescriptor().getModuleRevisionId();
46 // make dependency tree easier to fetch informations
47 for (Iterator iterator = report.getDependencies().iterator(); iterator.hasNext();) {
48 IvyNode dependency = (IvyNode) iterator.next();
49 populateDependencyTree(dependency, mrid, report);
47 // make dependency tree easier to fetch information
48 for (IvyNode dependency : report.getDependencies()) {
49 populateDependencyTree(dependency);
5050 }
51 printDependencies((List) dependencies.get(mrid), 0);
51 final List<IvyNode> dependencyList = dependencies.get(mrid);
52 if (dependencyList != null) {
53 printDependencies(mrid, dependencyList, 0, new HashSet<ModuleRevisionId>());
54 }
5255 }
5356
54 private void printDependencies(List/* <IvyNode> */dependencyList, int indent) {
55 for (Iterator iterator = dependencyList.iterator(); iterator.hasNext();) {
56 IvyNode dependency = (IvyNode) iterator.next();
57 boolean evicted = dependency.isEvicted(getConf());
57 private void printDependencies(final ModuleRevisionId mrid, final List<IvyNode> dependencyList, final int indent,
58 final Set<ModuleRevisionId> ancestors) {
59 for (IvyNode dependency : dependencyList) {
60 final Set<ModuleRevisionId> ancestorsForCurrentDep = new HashSet<>(ancestors);
61 // previous ancestors plus the module to whom these dependencies belong to
62 ancestorsForCurrentDep.add(mrid);
63 final boolean evicted = dependency.isEvicted(getConf());
5864 if (evicted && !showEvicted) {
5965 continue;
6066 }
61 StringBuffer sb = new StringBuffer();
67 final boolean isLastDependency = dependencyList.indexOf(dependency) == dependencyList.size() - 1;
68 final StringBuilder sb = new StringBuilder();
69 final ModuleRevisionId dependencyMrid = dependency.getId();
70 final boolean circular = ancestorsForCurrentDep.contains(dependencyMrid);
6271 if (indent > 0) {
6372 for (int i = 0; i < indent; i++) {
64 if (i == indent - 1 && !iterator.hasNext() && !hasDependencies(dependency)) {
73 if (i == indent - 1 && isLastDependency && !hasDependencies(dependency)) {
6574 sb.append(" ");
6675 } else {
6776 sb.append("| ");
6978
7079 }
7180 }
72 if (iterator.hasNext()) {
73 sb.append("+- ");
81 sb.append(isLastDependency ? "\\- " : "+- ");
82 if (!evicted && circular) {
83 // log and skip processing the (transitive) dependencies of this dependency
84 sb.append("(circularly depends on) ").append(dependencyMrid);
85 log(sb.toString());
86 continue;
7487 } else {
75 sb.append("\\- ");
88 sb.append(dependencyMrid.toString());
7689 }
77 sb.append(dependency.getId().toString());
7890 if (evicted && showEvicted) {
7991 EvictionData evictedData = dependency.getEvictedData(getConf());
8092 if (evictedData.isTransitivelyEvicted()) {
90102 }
91103 log(sb.toString());
92104
93 printDependencies((List) dependencies.get(dependency.getId()), indent + 1);
105 printDependencies(dependencyMrid, dependencies.get(dependencyMrid), indent + 1, ancestorsForCurrentDep);
94106 }
95107 }
96108
97 private boolean hasDependencies(IvyNode dependency) {
98 List dependencyList = (List) dependencies.get(dependency.getId());
99 return dependencyList.size() > 0;
109 private boolean hasDependencies(final IvyNode module) {
110 if (module == null) {
111 return false;
112 }
113 final List<IvyNode> dependenciesForModule = dependencies.get(module.getId());
114 return dependenciesForModule != null && !dependenciesForModule.isEmpty();
100115 }
101116
102 private void populateDependencyTree(IvyNode dependency, ModuleRevisionId currentMrid,
103 ResolveReport report) {
117 private void populateDependencyTree(IvyNode dependency) {
104118 registerNodeIfNecessary(dependency.getId());
105 for (int i = 0; i < dependency.getAllCallers().length; i++) {
106 Caller caller = dependency.getAllCallers()[i];
119 for (Caller caller : dependency.getAllCallers()) {
107120 addDependency(caller.getModuleRevisionId(), dependency);
108121 }
109122 }
110123
111 private void registerNodeIfNecessary(ModuleRevisionId moduleRevisionId) {
124 private void registerNodeIfNecessary(final ModuleRevisionId moduleRevisionId) {
112125 if (!dependencies.containsKey(moduleRevisionId)) {
113 dependencies.put(moduleRevisionId, new ArrayList/* <IvyNode> */());
126 dependencies.put(moduleRevisionId, new ArrayList<IvyNode>());
114127 }
115128 }
116129
117 private void addDependency(ModuleRevisionId moduleRevisionId, IvyNode dependency) {
130 private void addDependency(final ModuleRevisionId moduleRevisionId, final IvyNode dependency) {
118131 registerNodeIfNecessary(moduleRevisionId);
119 List/* <IvyNode> */list = (List) dependencies.get(moduleRevisionId);
120 list.add(dependency);
132 dependencies.get(moduleRevisionId).add(dependency);
121133 }
122134
123135 public boolean isShowEvicted() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.IOException;
2020 import java.text.ParseException;
2121 import java.util.ArrayList;
22 import java.util.Iterator;
2322 import java.util.List;
2423
2524 import org.apache.ivy.core.module.descriptor.Configuration;
3130 import org.apache.ivy.core.resolve.IvyNode;
3231 import org.apache.ivy.core.resolve.ResolveOptions;
3332 import org.apache.tools.ant.BuildException;
33
34 import static org.apache.ivy.util.StringUtils.splitToArray;
3435
3536 public class IvyDependencyUpdateChecker extends IvyPostResolveTask {
3637
5152 originalModuleDescriptor.getModuleRevisionId(),
5253 originalModuleDescriptor.getStatus(), originalModuleDescriptor.getPublicationDate());
5354 // copy configurations
54 for (int i = 0; i < originalModuleDescriptor.getConfigurations().length; i++) {
55 Configuration configuration = originalModuleDescriptor.getConfigurations()[i];
55 for (Configuration configuration : originalModuleDescriptor.getConfigurations()) {
5656 latestModuleDescriptor.addConfiguration(configuration);
5757 }
5858 // clone dependency and add new one with the requested revisionToCheck
59 for (int i = 0; i < originalModuleDescriptor.getDependencies().length; i++) {
60 DependencyDescriptor dependencyDescriptor = originalModuleDescriptor.getDependencies()[i];
59 for (DependencyDescriptor dependencyDescriptor : originalModuleDescriptor.getDependencies()) {
6160 ModuleRevisionId upToDateMrid = ModuleRevisionId.newInstance(
6261 dependencyDescriptor.getDependencyRevisionId(), revisionToCheck);
6362 latestModuleDescriptor.addDependency(dependencyDescriptor.clone(upToDateMrid));
6766 ResolveOptions resolveOptions = new ResolveOptions();
6867 resolveOptions.setDownload(isDownload());
6968 resolveOptions.setLog(getLog());
70 resolveOptions.setConfs(splitConfs(getConf()));
69 resolveOptions.setConfs(splitToArray(getConf()));
7170 resolveOptions.setCheckIfChanged(checkIfChanged);
7271
7372 ResolveReport latestReport;
8180 displayMissingDependencyOnLatest(getResolvedReport(), latestReport);
8281 }
8382
84 } catch (ParseException e) {
85 throw new BuildException("impossible to resolve dependencies:\n\t" + e, e);
86 } catch (IOException e) {
83 } catch (ParseException | IOException e) {
8784 throw new BuildException("impossible to resolve dependencies:\n\t" + e, e);
8885 }
8986
9289 private void displayDependencyUpdates(ResolveReport originalReport, ResolveReport latestReport) {
9390 log("Dependencies updates available :");
9491 boolean dependencyUpdateDetected = false;
95 for (Iterator iterator = latestReport.getDependencies().iterator(); iterator.hasNext();) {
96 IvyNode latest = (IvyNode) iterator.next();
97 for (Iterator iterator2 = originalReport.getDependencies().iterator(); iterator2
98 .hasNext();) {
99 IvyNode originalDependency = (IvyNode) iterator2.next();
92 for (IvyNode latest : latestReport.getDependencies()) {
93 for (IvyNode originalDependency : originalReport.getDependencies()) {
10094 if (originalDependency.getModuleId().equals(latest.getModuleId())) {
10195 if (!originalDependency.getResolvedId().getRevision()
10296 .equals(latest.getResolvedId().getRevision())) {
103 // is this dependency a transitive dependency ? or direct dependency
104 // (unfortunatly
105 // .isTranstive() methods doesn't have the same meaning)
97 // is this dependency a transitive or a direct dependency?
98 // (unfortunately .isTransitive() methods do not have the same meaning)
10699 boolean isTransitiveDependency = latest.getDependencyDescriptor(latest
107100 .getRoot()) == null;
108 if ((!isTransitiveDependency) || (isTransitiveDependency && showTransitive)) {
109 StringBuffer sb = new StringBuffer();
110 sb.append("\t")//
111 .append(originalDependency.getResolvedId().getOrganisation()) //
112 .append('#')//
113 .append(originalDependency.getResolvedId().getName())//
114 .append(isTransitiveDependency ? " (transitive)" : "") //
115 .append("\t")//
116 .append(originalDependency.getResolvedId().getRevision())//
117 .append(" -> ")//
118 .append(latest.getResolvedId().getRevision());
119 log(sb.toString());
101 if (!isTransitiveDependency || showTransitive) {
102 log(String.format("\t%s#%s%s\t%s -> %s",
103 originalDependency.getResolvedId().getOrganisation(),
104 originalDependency.getResolvedId().getName(),
105 isTransitiveDependency ? " (transitive)" : "",
106 originalDependency.getResolvedId().getRevision(),
107 latest.getResolvedId().getRevision()));
120108 dependencyUpdateDetected = true;
121109 }
122110 }
131119
132120 private void displayMissingDependencyOnLatest(ResolveReport originalReport,
133121 ResolveReport latestReport) {
134 List/* <ModuleRevisionId> */listOfMissingDependencyOnLatest = new ArrayList/*
135 * <ModuleRevisionId
136 * >
137 */();
138 for (Iterator iterator = originalReport.getDependencies().iterator(); iterator.hasNext();) {
139 IvyNode originalDependency = (IvyNode) iterator.next();
122 List<ModuleRevisionId> listOfMissingDependencyOnLatest = new ArrayList<>();
123 for (IvyNode originalDependency : originalReport.getDependencies()) {
140124 boolean dependencyFound = false;
141 for (Iterator iterator2 = latestReport.getDependencies().iterator(); iterator2
142 .hasNext();) {
143 IvyNode latest = (IvyNode) iterator2.next();
125 for (IvyNode latest : latestReport.getDependencies()) {
144126 if (originalDependency.getModuleId().equals(latest.getModuleId())) {
145127 dependencyFound = true;
146128 }
152134
153135 if (listOfMissingDependencyOnLatest.size() > 0) {
154136 log("List of missing dependency on latest resolve :");
155 for (Iterator iterator = listOfMissingDependencyOnLatest.iterator(); iterator.hasNext();) {
156 ModuleRevisionId moduleRevisionId = (ModuleRevisionId) iterator.next();
137 for (ModuleRevisionId moduleRevisionId : listOfMissingDependencyOnLatest) {
157138 log("\t" + moduleRevisionId.toString());
158139 }
159140 }
161142
162143 private void displayNewDependencyOnLatest(ResolveReport originalReport,
163144 ResolveReport latestReport) {
164 List/* <ModuleRevisionId> */listOfNewDependencyOnLatest = new ArrayList/* <ModuleRevisionId> */();
165 for (Iterator iterator = latestReport.getDependencies().iterator(); iterator.hasNext();) {
166 IvyNode latest = (IvyNode) iterator.next();
167
145 List<ModuleRevisionId> listOfNewDependencyOnLatest = new ArrayList<>();
146 for (IvyNode latest : latestReport.getDependencies()) {
168147 boolean dependencyFound = false;
169 for (Iterator iterator2 = originalReport.getDependencies().iterator(); iterator2
170 .hasNext();) {
171 IvyNode originalDependency = (IvyNode) iterator2.next();
148 for (IvyNode originalDependency : originalReport.getDependencies()) {
172149 if (originalDependency.getModuleId().equals(latest.getModuleId())) {
173150 dependencyFound = true;
174151 }
179156 }
180157 if (listOfNewDependencyOnLatest.size() > 0) {
181158 log("List of new dependency on latest resolve :");
182 for (Iterator iterator = listOfNewDependencyOnLatest.iterator(); iterator.hasNext();) {
183 ModuleRevisionId moduleRevisionId = (ModuleRevisionId) iterator.next();
159 for (ModuleRevisionId moduleRevisionId : listOfNewDependencyOnLatest) {
184160 log("\t" + moduleRevisionId.toString());
185161 }
186162 }
210186 this.showTransitive = showTransitive;
211187 }
212188
189 public boolean isCheckIfChanged() {
190 return checkIfChanged;
191 }
192
193 public void setCheckIfChanged(boolean checkIfChanged) {
194 this.checkIfChanged = checkIfChanged;
195 }
213196 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6161 }
6262
6363 DefaultExcludeRule asRule(IvySettings settings) {
64 String matcherName = matcher == null ? PatternMatcher.EXACT : matcher;
65 String orgPattern = org == null ? PatternMatcher.ANY_EXPRESSION : org;
66 String modulePattern = module == null ? PatternMatcher.ANY_EXPRESSION : module;
67 String artifactPattern = artifact == null ? PatternMatcher.ANY_EXPRESSION : artifact;
68 String typePattern = type == null ? PatternMatcher.ANY_EXPRESSION : type;
69 String extPattern = ext == null ? typePattern : ext;
64 String matcherName = (matcher == null) ? PatternMatcher.EXACT : matcher;
65 String orgPattern = (org == null) ? PatternMatcher.ANY_EXPRESSION : org;
66 String modulePattern = (module == null) ? PatternMatcher.ANY_EXPRESSION : module;
67 String artifactPattern = (artifact == null) ? PatternMatcher.ANY_EXPRESSION : artifact;
68 String typePattern = (type == null) ? PatternMatcher.ANY_EXPRESSION : type;
69 String extPattern = (ext == null) ? typePattern : ext;
7070 ArtifactId aid = new ArtifactId(new ModuleId(orgPattern, modulePattern), artifactPattern,
7171 typePattern, extPattern);
7272 return new DefaultExcludeRule(aid, settings.getMatcher(matcherName), null);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.io.StringWriter;
2424 import java.io.Writer;
2525 import java.util.ArrayList;
26 import java.util.Arrays;
2726 import java.util.HashMap;
2827 import java.util.HashSet;
29 import java.util.Iterator;
3028 import java.util.List;
3129 import java.util.Map;
3230 import java.util.Set;
6664
6765 private String status;
6866
69 private List ignoredPackaged = new ArrayList(); // List (String package)
70
71 private Map mapping = new HashMap(); // Map (String package -> ModuleRevisionId)
67 private final List<String> ignoredPackaged = new ArrayList<>(); // List (String package)
68
69 private final Map<String, ModuleRevisionId> mapping = new HashMap<>();
70 // Map(String package -> ModuleRevisionId)
7271
7372 private Concat concat = new Concat();
7473
131130 Writer out = new StringWriter();
132131 concat.setWriter(out);
133132 concat.execute();
134 Set importsSet = new HashSet(Arrays.asList(out.toString().split("\n")));
135 Set dependencies = new HashSet();
136 for (Iterator iter = importsSet.iterator(); iter.hasNext();) {
137 String pack = ((String) iter.next()).trim();
138 ModuleRevisionId mrid = getMapping(pack);
133 Set<ModuleRevisionId> dependencies = new HashSet<>();
134 for (String pack : out.toString().split("\n")) {
135 ModuleRevisionId mrid = getMapping(pack.trim());
139136 if (mrid != null) {
140137 dependencies.add(mrid);
141138 }
142139 }
143140 try {
144141 PrintWriter writer = new PrintWriter(new FileOutputStream(to));
145 writer.println("<ivy-module version=\"1.0\">");
146 writer.println("\t<info organisation=\"" + organisation + "\"");
147 writer.println("\t module=\"" + module + "\"");
142 writer.println(String.format("<ivy-module version=\"1.0\">%n\t<info organisation=\"%s\"%n\t module=\"%s\"",
143 organisation, module));
148144 if (revision != null) {
149145 writer.println("\t revision=\"" + revision + "\"");
150146 }
151 if (status != null) {
152 writer.println("\t status=\"" + status + "\"");
153 } else {
154 writer.println("\t status=\"integration\"");
155 }
156 writer.println("\t/>");
147 writer.println(String.format("\t status=\"%s\"%n\t/>",
148 (status == null) ? "integration" : status));
157149 if (!dependencies.isEmpty()) {
158150 writer.println("\t<dependencies>");
159 for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
160 ModuleRevisionId mrid = (ModuleRevisionId) iter.next();
161 writer.println("\t\t<dependency org=\"" + mrid.getOrganisation() + "\" name=\""
162 + mrid.getName() + "\" rev=\"" + mrid.getRevision() + "\"/>");
151 for (ModuleRevisionId mrid : dependencies) {
152 writer.println(String.format("\t\t<dependency org=\"%s\" name=\"%s\" rev=\"%s\"/>",
153 mrid.getOrganisation(), mrid.getName(), mrid.getRevision()));
163154 }
164155 writer.println("\t</dependencies>");
165156 }
172163 }
173164
174165 /**
175 * @param pack
176 * @return
166 * @param pack String
167 * @return ModuleRevisionId
177168 */
178169 private ModuleRevisionId getMapping(String pack) {
179170 String askedPack = pack;
180171 ModuleRevisionId ret = null;
181 while (ret == null && pack.length() > 0) {
172 while (ret == null && !pack.isEmpty()) {
182173 if (ignoredPackaged.contains(pack)) {
183174 return null;
184175 }
185 ret = (ModuleRevisionId) mapping.get(pack);
176 ret = mapping.get(pack);
186177 int lastDotIndex = pack.lastIndexOf('.');
187178 if (lastDotIndex != -1) {
188179 pack = pack.substring(0, lastDotIndex);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.net.MalformedURLException;
2121 import java.text.ParseException;
2222 import java.util.ArrayList;
23 import java.util.Iterator;
23 import java.util.Arrays;
2424 import java.util.List;
2525 import java.util.Map;
26 import java.util.Map.Entry;
2726
2827 import org.apache.ivy.Ivy;
2928 import org.apache.ivy.core.module.descriptor.Artifact;
3029 import org.apache.ivy.core.module.descriptor.Configuration;
31 import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
3230 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3331 import org.apache.ivy.core.module.id.ModuleId;
3432 import org.apache.ivy.core.module.id.ModuleRevisionId;
3836 import org.apache.tools.ant.BuildException;
3937 import org.apache.tools.ant.Project;
4038
39 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
40
4141 /**
4242 * Parses information about an ivy file and make them available in ant.
4343 */
161161 Long.toString(md.getPublicationDate().getTime()));
162162 }
163163
164 Map extra = mrid.getExtraAttributes();
165 for (Iterator iter = extra.entrySet().iterator(); iter.hasNext();) {
166 Entry entry = (Entry) iter.next();
164 for (Map.Entry<String, String> entry : mrid.getExtraAttributes().entrySet()) {
167165 getProject().setProperty(property + ".extra." + entry.getKey(),
168 (String) entry.getValue());
166 entry.getValue());
169167 }
170168
171169 getProject().setProperty(property + ".configurations",
172170 mergeConfs(md.getConfigurationsNames()));
173171
174172 // store the public configurations in a separate property
175 Configuration[] configs = md.getConfigurations();
176 List publicConfigsList = new ArrayList();
177 for (int i = 0; i < configs.length; i++) {
178 String name = configs[i].getName();
179 if (Visibility.PUBLIC.equals(configs[i].getVisibility())) {
173 List<String> publicConfigsList = new ArrayList<>();
174 for (Configuration config : md.getConfigurations()) {
175 String name = config.getName();
176 if (PUBLIC.equals(config.getVisibility())) {
180177 publicConfigsList.add(name);
181178 }
182179
183 if (configs[i].getDescription() != null) {
180 if (config.getDescription() != null) {
184181 getProject().setProperty(property + ".configuration." + name + ".desc",
185 configs[i].getDescription());
186 }
187 }
188 String[] publicConfigs = (String[]) publicConfigsList.toArray(new String[publicConfigsList
189 .size()]);
182 config.getDescription());
183 }
184 }
185 String[] publicConfigs = publicConfigsList.toArray(new String[publicConfigsList.size()]);
190186 getProject().setProperty(property + ".public.configurations", mergeConfs(publicConfigs));
191187
192 Artifact[] artifacts = md.getAllArtifacts();
193 for (int i = 0; i < artifacts.length; i++) {
194 int id = i + 1;
195 getProject()
196 .setProperty(property + ".artifact." + id + ".name", artifacts[i].getName());
197 getProject()
198 .setProperty(property + ".artifact." + id + ".type", artifacts[i].getType());
199 getProject().setProperty(property + ".artifact." + id + ".ext", artifacts[i].getExt());
188 List<Artifact> artifacts = Arrays.asList(md.getAllArtifacts());
189 for (Artifact artifact : artifacts) {
190 int id = artifacts.indexOf(artifact) + 1;
191 getProject().setProperty(property + ".artifact." + id + ".name", artifact.getName());
192 getProject().setProperty(property + ".artifact." + id + ".type", artifact.getType());
193 getProject().setProperty(property + ".artifact." + id + ".ext", artifact.getExt());
200194 getProject().setProperty(property + ".artifact." + id + ".conf",
201 mergeConfs(artifacts[i].getConfigurations()));
202
203 Map artiExtra = artifacts[i].getExtraAttributes();
204 for (Iterator iter = artiExtra.entrySet().iterator(); iter.hasNext();) {
205 Entry entry = (Entry) iter.next();
195 mergeConfs(artifact.getConfigurations()));
196
197 for (Map.Entry<String, String> entry : artifact.getExtraAttributes().entrySet()) {
206198 getProject().setProperty(property + ".artifact." + id + ".extra." + entry.getKey(),
207 (String) entry.getValue());
199 entry.getValue());
208200 }
209201 }
210202 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6363 IvySettings settings = ivy.getSettings();
6464 if (organisation == null) {
6565 throw new BuildException("no organisation provided for ivy publish task: "
66 + "It can either be set explicitely via the attribute 'organisation' "
66 + "It can either be set explicitly via the attribute 'organisation' "
6767 + "or via 'ivy.organisation' property or a prior call to <resolve/>");
6868 }
69 if (module == null && PatternMatcher.EXACT.equals(matcher)) {
70 throw new BuildException("no module name provided for ivy publish task: "
71 + "It can either be set explicitely via the attribute 'module' "
72 + "or via 'ivy.module' property or a prior call to <resolve/>");
73 } else if (module == null && !PatternMatcher.EXACT.equals(matcher)) {
69 if (module == null) {
70 if (PatternMatcher.EXACT.equals(matcher)) {
71 throw new BuildException("no module name provided for ivy publish task: "
72 + "It can either be set explicitly via the attribute 'module' "
73 + "or via 'ivy.module' property or a prior call to <resolve/>");
74 }
7475 module = PatternMatcher.ANY_EXPRESSION;
7576 }
76 if (revision == null && PatternMatcher.EXACT.equals(matcher)) {
77 throw new BuildException("no module revision provided for ivy publish task: "
78 + "It can either be set explicitely via the attribute 'revision' "
79 + "or via 'ivy.revision' property or a prior call to <resolve/>");
80 } else if (revision == null && !PatternMatcher.EXACT.equals(matcher)) {
77 if (revision == null) {
78 if (PatternMatcher.EXACT.equals(matcher)) {
79 throw new BuildException("no module revision provided for ivy publish task: "
80 + "It can either be set explicitly via the attribute 'revision' "
81 + "or via 'ivy.revision' property or a prior call to <resolve/>");
82 }
8183 revision = PatternMatcher.ANY_EXPRESSION;
8284 }
83 if (branch == null && PatternMatcher.EXACT.equals(matcher)) {
84 branch = settings.getDefaultBranch(ModuleId.newInstance(organisation, module));
85 } else if (branch == null && !PatternMatcher.EXACT.equals(matcher)) {
86 branch = PatternMatcher.ANY_EXPRESSION;
85 if (branch == null) {
86 if (PatternMatcher.EXACT.equals(matcher)) {
87 branch = settings.getDefaultBranch(ModuleId.newInstance(organisation, module));
88 } else {
89 branch = PatternMatcher.ANY_EXPRESSION;
90 }
8791 }
8892 if (from == null) {
8993 throw new BuildException(
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
148148 patternMatcher);
149149 }
150150
151 for (int i = 0; i < mrids.length; i++) {
152 String name = IvyPatternHelper.substitute(settings.substitute(property), mrids[i]);
153 String value = IvyPatternHelper.substitute(settings.substitute(this.value), mrids[i]);
151 for (ModuleRevisionId mrid : mrids) {
152 String name = IvyPatternHelper.substitute(settings.substitute(property), mrid);
153 String value = IvyPatternHelper.substitute(settings.substitute(this.value), mrid);
154154 getProject().setProperty(name, value);
155155 }
156156 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.net.MalformedURLException;
2222 import java.text.ParseException;
2323 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.HashMap;
26 import java.util.Iterator;
24 import java.util.LinkedHashMap;
2725 import java.util.List;
2826 import java.util.Map;
2927
3028 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3129 import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorWriter;
3230 import org.apache.ivy.plugins.parser.m2.PomWriterOptions;
31 import org.apache.ivy.plugins.parser.m2.PomWriterOptions.ExtraDependency;
3332 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
3433 import org.apache.ivy.util.FileUtil;
3534 import org.apache.tools.ant.BuildException;
3635 import org.apache.tools.ant.Project;
36
37 import static org.apache.ivy.util.StringUtils.splitToArray;
3738
3839 /**
3940 * Convert an ivy file to a pom
151152
152153 private String description;
153154
154 private Collection mappings = new ArrayList();
155
156 private Collection dependencies = new ArrayList();
155 private List<Mapping> mappings = new ArrayList<>();
156
157 private List<Dependency> dependencies = new ArrayList<>();
157158
158159 public File getPomFile() {
159160 return pomFile;
239240 return dependency;
240241 }
241242
243 @Override
242244 public void doExecute() throws BuildException {
243245 try {
244246 if (ivyFile == null) {
264266
265267 private PomWriterOptions getPomWriterOptions() throws IOException {
266268 PomWriterOptions options = new PomWriterOptions();
267 options.setConfs(splitConfs(conf)).setArtifactName(getArtifactName())
269 options.setConfs(splitToArray(conf)).setArtifactName(getArtifactName())
268270 .setArtifactPackaging(getArtifactPackaging()).setPrintIvyInfo(isPrintIvyInfo())
269271 .setDescription(getDescription()).setExtraDependencies(getDependencies())
270272 .setTemplate(getTemplateFile());
280282 return options;
281283 }
282284
283 private Map getMappingsMap() {
284 Map mappingsMap = new HashMap();
285 for (Iterator iter = mappings.iterator(); iter.hasNext();) {
286 Mapping mapping = (Mapping) iter.next();
287 String[] mappingConfs = splitConfs(mapping.getConf());
288 for (int i = 0; i < mappingConfs.length; i++) {
289 if (!mappingsMap.containsKey(mappingConfs[i])) {
290 mappingsMap.put(mappingConfs[i], mapping.getScope());
285 private Map<String, String> getMappingsMap() {
286 Map<String, String> mappingsMap = new LinkedHashMap<>();
287 for (Mapping mapping : mappings) {
288 for (String mappingConf : splitToArray(mapping.getConf())) {
289 if (!mappingsMap.containsKey(mappingConf)) {
290 mappingsMap.put(mappingConf, mapping.getScope());
291291 }
292292 }
293293 }
294294 return mappingsMap;
295295 }
296296
297 private List getDependencies() {
298 List result = new ArrayList();
299 for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
300 Dependency dependency = (Dependency) iter.next();
301 result.add(new PomWriterOptions.ExtraDependency(dependency.getGroup(), dependency
302 .getArtifact(), dependency.getVersion(), dependency.getScope(), dependency
303 .getType(), dependency.getClassifier(), dependency.getOptional()));
297 private List<ExtraDependency> getDependencies() {
298 List<ExtraDependency> result = new ArrayList<>();
299 for (Dependency dependency : dependencies) {
300 result.add(new ExtraDependency(dependency.getGroup(), dependency.getArtifact(),
301 dependency.getVersion(), dependency.getScope(), dependency.getType(),
302 dependency.getClassifier(), dependency.getOptional()));
304303 }
305304 return result;
306305 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5555 }
5656
5757 void addOverride(DefaultModuleDescriptor md, IvySettings settings) {
58 String matcherName = matcher == null ? PatternMatcher.EXACT : matcher;
59 String orgPattern = org == null ? PatternMatcher.ANY_EXPRESSION : org;
60 String modulePattern = module == null ? PatternMatcher.ANY_EXPRESSION : module;
58 String matcherName = (matcher == null) ? PatternMatcher.EXACT : matcher;
59 String orgPattern = (org == null) ? PatternMatcher.ANY_EXPRESSION : org;
60 String modulePattern = (module == null) ? PatternMatcher.ANY_EXPRESSION : module;
6161 md.addDependencyDescriptorMediator(new ModuleId(orgPattern, modulePattern),
6262 settings.getMatcher(matcherName), new OverrideDependencyDescriptorMediator(branch, rev));
6363 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.util.Arrays;
2121 import java.util.HashSet;
22 import java.util.Iterator;
22 import java.util.Set;
2323
2424 import org.apache.ivy.Ivy;
2525 import org.apache.ivy.core.cache.ResolutionCacheManager;
26 import org.apache.ivy.core.module.descriptor.Artifact;
2627 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
2728 import org.apache.ivy.core.module.id.ModuleId;
2829 import org.apache.ivy.core.module.id.ModuleRevisionId;
3031 import org.apache.ivy.core.resolve.ResolveOptions;
3132 import org.apache.ivy.core.settings.IvySettings;
3233 import org.apache.ivy.util.Message;
33 import org.apache.ivy.util.StringUtils;
3434 import org.apache.ivy.util.filter.Filter;
3535 import org.apache.ivy.util.filter.FilterHelper;
3636 import org.apache.tools.ant.BuildException;
37
38 import static org.apache.ivy.util.StringUtils.joinArray;
39 import static org.apache.ivy.util.StringUtils.splitToArray;
3740
3841 /**
3942 * Base class for tasks needing to be performed after a resolve.
6164
6265 private File file;
6366
64 private Filter artifactFilter = null;
67 private Filter<Artifact> artifactFilter = null;
6568
6669 private boolean useOrigin = false;
6770
109112 Ivy ivy = getIvyInstance();
110113 IvySettings settings = ivy.getSettings();
111114
112 boolean orgAndModSetManually = (organisation != null) && (module != null);
115 boolean orgAndModSetManually = organisation != null && module != null;
113116
114117 organisation = getProperty(organisation, settings, "ivy.organisation");
115118 module = getProperty(module, settings, "ivy.module");
122125 }
123126
124127 if (isInline()) {
125 conf = conf == null ? "*" : conf;
128 if (conf == null) {
129 conf = "*";
130 }
126131 if (organisation == null) {
127132 throw new BuildException(
128133 "no organisation provided for ivy cache task in inline mode: "
129 + "It can either be set explicitely via the attribute 'organisation' "
134 + "It can either be set explicitly via the attribute 'organisation' "
130135 + "or via 'ivy.organisation' property");
131136 }
132137 if (module == null) {
133138 throw new BuildException(
134139 "no module name provided for ivy cache task in inline mode: "
135 + "It can either be set explicitely via the attribute 'module' "
140 + "It can either be set explicitly via the attribute 'module' "
136141 + "or via 'ivy.module' property");
137142 }
138143 String[] toResolve = getConfsToResolve(getOrganisation(), getModule() + "-caller",
144149 }
145150 }
146151 if (toResolve.length > 0) {
147 Message.verbose("using inline mode to resolve " + getOrganisation() + " "
148 + getModule() + " " + getRevision() + " ("
149 + StringUtils.join(toResolve, ", ") + ")");
152 Message.verbose(String.format("using inline mode to resolve %s %s %s (%s)",
153 getOrganisation(), getModule(), getRevision(), joinArray(toResolve, ", ")));
150154 IvyResolve resolve = setupResolve(isHaltonfailure(), isUseOrigin());
151155 resolve.setOrganisation(getOrganisation());
152156 resolve.setModule(getModule());
159163 resolve.setTransitive(isTransitive());
160164 resolve.execute();
161165 } else {
162 Message.verbose("inline resolve already done for " + getOrganisation() + " "
163 + getModule() + " " + getRevision() + " (" + conf + ")");
166 Message.verbose(String.format("inline resolve already done for %s %s %s (%s)",
167 getOrganisation(), getModule(), getRevision(), conf));
164168 }
165169 if ("*".equals(conf)) {
166 conf = StringUtils.join(
170 conf = joinArray(
167171 getResolvedConfigurations(getOrganisation(), getModule() + "-caller", true),
168172 ", ");
169173 }
191195 module = getProperty(module, settings, "ivy.module");
192196 if (organisation == null) {
193197 throw new BuildException("no organisation provided for ivy cache task: "
194 + "It can either be set explicitely via the attribute 'organisation' "
198 + "It can either be set explicitly via the attribute 'organisation' "
195199 + "or via 'ivy.organisation' property or a prior call to <resolve/>");
196200 }
197201 if (module == null) {
198202 throw new BuildException("no module name provided for ivy cache task: "
199 + "It can either be set explicitely via the attribute 'module' "
203 + "It can either be set explicitly via the attribute 'module' "
200204 + "or via 'ivy.module' property or a prior call to <resolve/>");
201205 }
202206 if (conf == null) {
203207 throw new BuildException("no conf provided for ivy cache task: "
204 + "It can either be set explicitely via the attribute 'conf' or "
208 + "It can either be set explicitly via the attribute 'conf' or "
205209 + "via 'ivy.resolved.configurations' property or a prior call to <resolve/>");
206210 }
207211
211215 protected void ensureResolved(IvySettings settings) {
212216 String requestedConfigs = getProperty(getConf(), settings, "ivy.resolved.configurations");
213217
214 String[] confs = null;
215 if (getResolveId() != null) {
216 confs = getConfsToResolve(getResolveId(), requestedConfigs);
217 } else {
218 confs = getConfsToResolve(getOrganisation(), getModule(), requestedConfigs, false);
219 }
218 String[] confs = (getResolveId() == null)
219 ? getConfsToResolve(getOrganisation(), getModule(), requestedConfigs, false)
220 : getConfsToResolve(getResolveId(), requestedConfigs);
220221
221222 if (confs.length > 0) {
222223 IvyResolve resolve = setupResolve(isHaltonfailure(), isUseOrigin());
223224 resolve.setFile(getFile());
224225 resolve.setTransitive(isTransitive());
225 resolve.setConf(StringUtils.join(confs, ", "));
226 resolve.setConf(joinArray(confs, ", "));
226227 resolve.setResolveId(getResolveId());
227228 resolve.execute();
228229 }
229230 }
230231
231232 protected String[] getConfsToResolve(String org, String module, String conf, boolean strict) {
232 ModuleDescriptor reference = (ModuleDescriptor) getResolvedDescriptor(org, module, strict);
233 ModuleDescriptor reference = getResolvedDescriptor(org, module, strict);
233234 String[] rconfs = getResolvedConfigurations(org, module, strict);
234235 return getConfsToResolve(reference, conf, rconfs);
235236 }
236237
237238 protected String[] getConfsToResolve(String resolveId, String conf) {
238 ModuleDescriptor reference = (ModuleDescriptor) getResolvedDescriptor(resolveId, false);
239 ModuleDescriptor reference = getResolvedDescriptor(resolveId, false);
239240 if (reference == null) {
240241 // assume the module has been resolved outside this build, resolve the required
241242 // configurations again
242243 // TODO: find a way to discover which confs were resolved by that previous resolve
243244 if (conf == null) {
244245 return new String[] {"*"};
245 } else {
246 return splitConfs(conf);
247 }
248 }
249 String[] rconfs = (String[]) getProject().getReference(
250 "ivy.resolved.configurations.ref." + resolveId);
246 }
247 return splitToArray(conf);
248 }
249 String[] rconfs = getProject().getReference("ivy.resolved.configurations.ref." + resolveId);
251250 return getConfsToResolve(reference, conf, rconfs);
252251 }
253252
258257 Message.debug("module not yet resolved, all confs still need to be resolved");
259258 if (conf == null) {
260259 return new String[] {"*"};
261 } else {
262 return splitConfs(conf);
263 }
264 } else if (conf != null) {
265 String[] confs;
266 if ("*".equals(conf)) {
267 confs = reference.getConfigurationsNames();
268 } else {
269 confs = splitConfs(conf);
270 }
271
272 HashSet rconfsSet = new HashSet(Arrays.asList(rconfs));
273
274 // for each resolved configuration, check if the report still exists
275 ResolutionCacheManager cache = getSettings().getResolutionCacheManager();
276 for (Iterator it = rconfsSet.iterator(); it.hasNext();) {
277 String resolvedConf = (String) it.next();
278 String resolveId = getResolveId();
279 if (resolveId == null) {
280 resolveId = ResolveOptions.getDefaultResolveId(reference);
281 }
282 File report = cache.getConfigurationResolveReportInCache(resolveId, resolvedConf);
283 if (!report.exists()) {
284 // the report doesn't exist any longer, we have to recreate it...
285 it.remove();
286 }
287 }
288
289 HashSet confsSet = new HashSet(Arrays.asList(confs));
290 Message.debug("resolved configurations: " + rconfsSet);
291 Message.debug("asked configurations: " + confsSet);
292 confsSet.removeAll(rconfsSet);
293 Message.debug("to resolve configurations: " + confsSet);
294 return (String[]) confsSet.toArray(new String[confsSet.size()]);
295 } else {
260 }
261 return splitToArray(conf);
262 }
263
264 if (conf == null) {
296265 Message.debug("module already resolved, no configuration to resolve");
297266 return new String[0];
298267 }
299268
269 String[] confs;
270 if ("*".equals(conf)) {
271 confs = reference.getConfigurationsNames();
272 } else {
273 confs = splitToArray(conf);
274 }
275
276 Set<String> rconfsSet = new HashSet<>();
277
278 // for each resolved configuration, check if the report still exists
279 ResolutionCacheManager cache = getSettings().getResolutionCacheManager();
280 for (String resolvedConf : rconfs) {
281 String resolveId = getResolveId();
282 if (resolveId == null) {
283 resolveId = ResolveOptions.getDefaultResolveId(reference);
284 }
285 File report = cache.getConfigurationResolveReportInCache(resolveId, resolvedConf);
286 // if the report does not exist any longer, we have to recreate it...
287 if (report.exists()) {
288 rconfsSet.add(resolvedConf);
289 }
290 }
291
292 Set<String> confsSet = new HashSet<>(Arrays.asList(confs));
293 Message.debug("resolved configurations: " + rconfsSet);
294 Message.debug("asked configurations: " + confsSet);
295 confsSet.removeAll(rconfsSet);
296 Message.debug("to resolve configurations: " + confsSet);
297 return confsSet.toArray(new String[confsSet.size()]);
300298 }
301299
302300 protected IvyResolve setupResolve(boolean haltOnFailure, boolean useOrigin) {
316314
317315 protected ModuleRevisionId getResolvedMrid() {
318316 return new ModuleRevisionId(getResolvedModuleId(),
319 getRevision() == null ? Ivy.getWorkingRevision() : getRevision());
317 (getRevision() == null) ? Ivy.getWorkingRevision() : getRevision());
320318 }
321319
322320 protected ModuleId getResolvedModuleId() {
389387 revision = rev;
390388 }
391389
392 public Filter getArtifactFilter() {
390 public Filter<Artifact> getArtifactFilter() {
393391 return artifactFilter;
394392 }
395393
426424 }
427425
428426 public void setKeep(boolean keep) {
429 this.keep = Boolean.valueOf(keep);
427 this.keep = keep;
430428 }
431429
432430 public boolean isKeep() {
433 return this.keep == null ? !isInline() : this.keep.booleanValue();
431 return this.keep == null ? !isInline() : this.keep;
434432 }
435433
436434 public void setChanging(boolean changing) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3636 import org.apache.tools.ant.BuildException;
3737 import org.apache.tools.ant.DynamicAttribute;
3838
39 import static org.apache.ivy.util.StringUtils.splitToArray;
40
3941 /**
4042 * This task allow to publish a module revision to an Ivy repository.
4143 */
6062
6163 private String publishResolverName = null;
6264
63 private List artifactspattern = new ArrayList();
65 private List<String> artifactspattern = new ArrayList<>();
6466
6567 private File deliveryList;
6668
8082
8183 private boolean forcedeliver;
8284
83 private Collection artifacts = new ArrayList();
85 private Collection<Artifact> artifacts = new ArrayList<>();
8486
8587 private String pubBranch;
8688
9799 }
98100
99101 /**
102 * @return String
100103 * @deprecated use {@link #getSrcivypattern()} instead.
101104 */
102105 @Deprecated
105108 }
106109
107110 /**
111 * @param destivypattern String
108112 * @deprecated use {@link #setSrcivypattern(String)} instead.
109113 */
110114 @Deprecated
189193 }
190194
191195 public String getArtifactspattern() {
192 return (String) (artifactspattern.isEmpty() ? null : artifactspattern.get(0));
196 return artifactspattern.isEmpty() ? null : artifactspattern.get(0);
193197 }
194198
195199 public void setArtifactspattern(String artifactsPattern) {
221225 this.merge = merge;
222226 }
223227
228 @Override
224229 public void doExecute() throws BuildException {
225230 Ivy ivy = getIvyInstance();
226231 IvySettings settings = ivy.getSettings();
242247 status = getProperty(status, settings, "ivy.status");
243248 if (organisation == null) {
244249 throw new BuildException("no organisation provided for ivy publish task: "
245 + "It can either be set explicitely via the attribute 'organisation' "
250 + "It can either be set explicitly via the attribute 'organisation' "
246251 + "or via 'ivy.organisation' property or a prior call to <resolve/>");
247252 }
248253 if (module == null) {
249254 throw new BuildException("no module name provided for ivy publish task: "
250 + "It can either be set explicitely via the attribute 'module' "
255 + "It can either be set explicitly via the attribute 'module' "
251256 + "or via 'ivy.module' property or a prior call to <resolve/>");
252257 }
253258 if (revision == null) {
254259 throw new BuildException("no module revision provided for ivy publish task: "
255 + "It can either be set explicitely via the attribute 'revision' "
260 + "It can either be set explicitly via the attribute 'revision' "
256261 + "or via 'ivy.revision' property or a prior call to <resolve/>");
257262 }
258263 if (artifactspattern.isEmpty()) {
311316 mrid,
312317 artifactspattern,
313318 publishResolverName,
314 new PublishOptions()
315 .setPubrevision(getPubrevision())
316 .setPubbranch(getPubbranch())
317 .setSrcIvyPattern(publishivy ? srcivypattern : null)
318 .setStatus(getStatus())
319 new PublishOptions().setPubrevision(getPubrevision()).setPubbranch(getPubbranch())
320 .setSrcIvyPattern(publishivy ? srcivypattern : null).setStatus(getStatus())
319321 .setPubdate(pubdate)
320 .setExtraArtifacts(
321 (Artifact[]) artifacts.toArray(new Artifact[artifacts.size()]))
322 .setExtraArtifacts(artifacts.toArray(new Artifact[artifacts.size()]))
322323 .setValidate(doValidate(settings)).setOverwrite(overwrite)
323324 .setUpdate(update).setMerge(merge).setWarnOnMissing(warnonmissing)
324 .setHaltOnMissing(haltonmissing).setConfs(splitConfs(conf)));
325 .setHaltOnMissing(haltonmissing).setConfs(splitToArray(conf)));
325326 } catch (Exception e) {
326327 if (e instanceof BuildException) {
327328 throw (BuildException) e;
391392
392393 private String type;
393394
394 private Map extra = new HashMap();
395 private Map<String, String> extra = new HashMap<>();
395396
396397 public String[] getConfigurations() {
397398 return null;
438439 }
439440
440441 public String getAttribute(String attName) {
441 return (String) extra.get(attName);
442 }
443
444 public Map getAttributes() {
442 return extra.get(attName);
443 }
444
445 public Map<String, String> getAttributes() {
445446 return extra;
446447 }
447448
448449 public String getExtraAttribute(String attName) {
449 return (String) extra.get(attName);
450 }
451
452 public Map getExtraAttributes() {
450 return extra.get(attName);
451 }
452
453 public Map<String, String> getExtraAttributes() {
453454 return extra;
454455 }
455456
456 public Map getQualifiedExtraAttributes() {
457 public Map<String, String> getQualifiedExtraAttributes() {
457458 return extra;
458459 }
459460
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import java.io.OutputStream;
2727 import java.text.ParseException;
2828 import java.util.ArrayList;
29 import java.util.Iterator;
3029 import java.util.List;
3130
3231 import javax.xml.transform.Source;
5251 import org.apache.tools.ant.taskdefs.XSLTProcess;
5352 import org.apache.tools.ant.util.JAXPUtils;
5453
54 import static org.apache.ivy.util.StringUtils.splitToArray;
55
5556 /**
5657 * This ant task let users generates reports (html, xml, graphml, ...) from the last resolve done.
5758 */
7879
7980 private String xslext = "html";
8081
81 private List params = new ArrayList();
82 private final List<XSLTProcess.Param> params = new ArrayList<>();
8283
8384 private String resolveId;
8485
162163 }
163164 if (conf == null) {
164165 throw new BuildException("no conf provided for ivy report task: "
165 + "It can either be set explicitely via the attribute 'conf' or "
166 + "It can either be set explicitly via the attribute 'conf' or "
166167 + "via 'ivy.resolved.configurations' property or a prior call to <resolve/>");
167168 }
168169 if (todir == null) {
189190
190191 if (organisation == null) {
191192 throw new BuildException("no organisation provided for ivy report task: "
192 + "It can either be set explicitely via the attribute 'organisation' or "
193 + "It can either be set explicitly via the attribute 'organisation' or "
193194 + "via 'ivy.organisation' property or a prior call to <resolve/>");
194195 }
195196 if (module == null) {
196197 throw new BuildException("no module name provided for ivy report task: "
197 + "It can either be set explicitely via the attribute 'module' or "
198 + "It can either be set explicitly via the attribute 'module' or "
198199 + "via 'ivy.module' property or a prior call to <resolve/>");
199200 }
200201
202203 }
203204
204205 try {
205 String[] confs = splitConfs(conf);
206 String[] confs = splitToArray(conf);
206207 if (xsl) {
207208 genreport(confs);
208209 }
222223
223224 private void genxml(String[] confs) throws IOException {
224225 ResolutionCacheManager cacheMgr = getIvyInstance().getResolutionCacheManager();
225 for (int i = 0; i < confs.length; i++) {
226 File xml = cacheMgr.getConfigurationResolveReportInCache(resolveId, confs[i]);
226 for (String config : confs) {
227 File xml = cacheMgr.getConfigurationResolveReportInCache(resolveId, config);
227228
228229 File out;
229 if (todir != null) {
230 out = new File(todir, getOutputPattern(confs[i], "xml"));
230 if (todir == null) {
231 out = getProject().resolveFile(getOutputPattern(config, "xml"));
231232 } else {
232 out = getProject().resolveFile(getOutputPattern(confs[i], "xml"));
233 out = new File(todir, getOutputPattern(config, "xml"));
233234 }
234235
235236 FileUtil.copy(xml, out, null);
242243 // copy the css if required
243244 if (xslFile == null) {
244245 File css;
245 if (todir != null) {
246 if (todir == null) {
247 css = getProject().resolveFile("ivy-report.css");
248 } else {
246249 css = new File(todir, "ivy-report.css");
247 } else {
248 css = getProject().resolveFile("ivy-report.css");
249250 }
250251
251252 if (!css.exists()) {
306307 out = getProject().getBaseDir();
307308 }
308309
309 InputStream xsltStream = null;
310 try {
310 try (InputStream xsltStream = new BufferedInputStream(new FileInputStream(style))) {
311311 // create stream to stylesheet
312 xsltStream = new BufferedInputStream(new FileInputStream(style));
313312 Source xsltSource = new StreamSource(xsltStream, JAXPUtils.getSystemId(style));
314313
315314 // create transformer
321320 transformer.setParameter("extension", xslext);
322321
323322 // add the provided XSLT parameters
324 for (Iterator it = params.iterator(); it.hasNext();) {
325 XSLTProcess.Param param = (XSLTProcess.Param) it.next();
323 for (XSLTProcess.Param param : params) {
326324 transformer.setParameter(param.getName(), param.getExpression());
327325 }
328326
329327 // create the report
330 for (int i = 0; i < confs.length; i++) {
331 File reportFile = cacheMgr
332 .getConfigurationResolveReportInCache(resolveId, confs[i]);
333 File outFile = new File(out, getOutputPattern(confs[i], ext));
328 for (String config : confs) {
329 File reportFile = cacheMgr.getConfigurationResolveReportInCache(resolveId, config);
330 File outFile = new File(out, getOutputPattern(config, ext));
334331
335332 log("Processing " + reportFile + " to " + outFile);
336333
343340 }
344341 }
345342
346 InputStream inStream = null;
347 OutputStream outStream = null;
348 try {
349 inStream = new BufferedInputStream(new FileInputStream(reportFile));
350 outStream = new BufferedOutputStream(new FileOutputStream(outFile));
343 try (InputStream inStream = new BufferedInputStream(new FileInputStream(reportFile));
344 OutputStream outStream = new BufferedOutputStream(new FileOutputStream(outFile))) {
351345 StreamResult res = new StreamResult(outStream);
352346 Source src = new StreamSource(inStream, JAXPUtils.getSystemId(style));
353347 transformer.transform(src, res);
354348 } catch (TransformerException e) {
355349 throw new BuildException(e);
356 } finally {
357 if (inStream != null) {
358 try {
359 inStream.close();
360 } catch (IOException e) {
361 // ignore
362 }
363 }
364 if (outStream != null) {
365 try {
366 outStream.close();
367 } catch (IOException e) {
368 // ignore
369 }
370 }
371350 }
372351 }
373352 } catch (TransformerConfigurationException e) {
374353 throw new BuildException(e);
375 } finally {
376 if (xsltStream != null) {
377 try {
378 xsltStream.close();
379 } catch (IOException e) {
380 // ignore
381 }
382 }
383354 }
384355 }
385356
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.io.IOException;
2121 import java.util.ArrayList;
2222 import java.util.HashSet;
23 import java.util.Iterator;
2423 import java.util.List;
2524 import java.util.Set;
2625
7069
7170 private String xslext = "html";
7271
73 private List params = new ArrayList();
72 private final List<XSLTProcess.Param> params = new ArrayList<>();
7473
7574 public void doExecute() throws BuildException {
7675 Ivy ivy = getIvyInstance();
8079 }
8180 if (module == null && PatternMatcher.EXACT.equals(matcher)) {
8281 throw new BuildException("no module name provided for ivy repository graph task: "
83 + "It can either be set explicitely via the attribute 'module' or "
82 + "It can either be set explicitly via the attribute 'module' or "
8483 + "via 'ivy.module' property or a prior call to <resolve/>");
8584 } else if (module == null && !PatternMatcher.EXACT.equals(matcher)) {
8685 module = PatternMatcher.ANY_EXPRESSION;
8786 }
88 ModuleRevisionId mrid = ModuleRevisionId.newInstance(organisation, module, revision);
87 ModuleRevisionId moduleRevisionId = ModuleRevisionId.newInstance(organisation, module, revision);
8988
9089 try {
91 ModuleRevisionId criteria = null;
92
93 if ((revision == null) || settings.getVersionMatcher().isDynamic(mrid)) {
94 criteria = new ModuleRevisionId(new ModuleId(organisation, module), branch, "*");
95 } else {
96 criteria = new ModuleRevisionId(new ModuleId(organisation, module), branch,
97 revision);
98 }
90 ModuleRevisionId criteria = (revision == null) || settings.getVersionMatcher().isDynamic(moduleRevisionId)
91 ? new ModuleRevisionId(new ModuleId(organisation, module), branch, "*")
92 : new ModuleRevisionId(new ModuleId(organisation, module), branch, revision);
9993
10094 ModuleRevisionId[] mrids = ivy.listModules(criteria, settings.getMatcher(matcher));
10195
10296 // replace all found revisions with the original requested revision
103 Set modules = new HashSet();
104 for (int i = 0; i < mrids.length; i++) {
105 modules.add(ModuleRevisionId.newInstance(mrids[i], revision));
106 }
107
108 mrids = (ModuleRevisionId[]) modules.toArray(new ModuleRevisionId[modules.size()]);
97 Set<ModuleRevisionId> modules = new HashSet<>();
98 for (ModuleRevisionId mrid : mrids) {
99 modules.add(ModuleRevisionId.newInstance(mrid, revision));
100 }
101
102 mrids = modules.toArray(new ModuleRevisionId[modules.size()]);
109103 ModuleDescriptor md = DefaultModuleDescriptor.newCallerInstance(mrids, true, false);
110104 String resolveId = ResolveOptions.getDefaultResolveId(md);
111105 ResolveReport report = ivy.resolve(md, new ResolveOptions().setResolveId(resolveId)
114108 ResolutionCacheManager cacheMgr = getIvyInstance().getResolutionCacheManager();
115109 new XmlReportOutputter().output(report, cacheMgr, new ResolveOptions());
116110 if (graph) {
117 gengraph(cacheMgr, md.getModuleRevisionId().getOrganisation(), md
118 .getModuleRevisionId().getName());
111 gengraph(cacheMgr, md.getModuleRevisionId().getOrganisation(),
112 md.getModuleRevisionId().getName());
119113 }
120114 if (dot) {
121 gendot(cacheMgr, md.getModuleRevisionId().getOrganisation(), md
122 .getModuleRevisionId().getName());
115 gendot(cacheMgr, md.getModuleRevisionId().getOrganisation(),
116 md.getModuleRevisionId().getName());
123117 }
124118 if (xml) {
125
126119 FileUtil.copy(cacheMgr.getConfigurationResolveReportInCache(resolveId, "default"),
127120 new File(getTodir(), outputname + ".xml"), null);
128121 }
129122 if (xsl) {
130 genreport(cacheMgr, md.getModuleRevisionId().getOrganisation(), md
131 .getModuleRevisionId().getName());
123 genreport(cacheMgr, md.getModuleRevisionId().getOrganisation(),
124 md.getModuleRevisionId().getName());
132125 }
133126 } catch (Exception e) {
134 throw new BuildException("impossible to generate graph for " + mrid + ": " + e, e);
135 }
136 }
137
138 private void genreport(ResolutionCacheManager cache, String organisation, String module)
139 throws IOException {
127 throw new BuildException("impossible to generate graph for " + moduleRevisionId + ": " + e, e);
128 }
129 }
130
131 private void genreport(ResolutionCacheManager cache, String organisation, String module) {
140132 // first process the report with xslt
141133 XSLTProcess xslt = new XSLTProcess();
142134 xslt.setTaskName(getTaskName());
149141
150142 xslt.setStyle(xslFile);
151143
152 XSLTProcess.Param param = xslt.createParam();
153 param.setName("extension");
154 param.setExpression(xslext);
144 XSLTProcess.Param xslExt = xslt.createParam();
145 xslExt.setName("extension");
146 xslExt.setExpression(xslext);
155147
156148 // add the provided XSLT parameters
157 for (Iterator it = params.iterator(); it.hasNext();) {
158 param = (XSLTProcess.Param) it.next();
149 for (XSLTProcess.Param param : params) {
159150 XSLTProcess.Param realParam = xslt.createParam();
160151 realParam.setName(param.getName());
161152 realParam.setExpression(param.getExpression());
194185 }
195186
196187 private void gen(ResolutionCacheManager cache, String organisation, String module,
197 String style, String ext) throws IOException {
188 String style, String ext) {
198189 XSLTProcess xslt = new XSLTProcess();
199190 xslt.setTaskName(getTaskName());
200191 xslt.setProject(getProject());
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.util.ArrayList;
2323 import java.util.Arrays;
2424 import java.util.Collection;
25 import java.util.Iterator;
2625 import java.util.List;
2726
2827 import org.apache.ivy.Ivy;
4241 import org.apache.tools.ant.BuildException;
4342 import org.apache.tools.ant.Project;
4443
44 import static org.apache.ivy.util.StringUtils.splitToArray;
45
4546 /**
4647 * This task allow to call the Ivy dependency resolution from ant.
4748 */
9091
9192 private boolean checkIfChanged = true; // for backward compatibility
9293
93 private List/* <IvyDependency> */dependencies = new ArrayList();
94
95 private List/* <IvyExclude> */excludes = new ArrayList();
96
97 private List/* <IvyConflict> */conflicts = new ArrayList();
94 private List<IvyDependency> dependencies = new ArrayList<>();
95
96 private List<IvyExclude> excludes = new ArrayList<>();
97
98 private List<IvyConflict> conflicts = new ArrayList<>();
9899
99100 public boolean isUseOrigin() {
100101 return useOrigin;
193194 }
194195
195196 /**
197 * @param failureProperty String
196198 * @deprecated Use {@link #setFailureProperty(String)} instead
197199 */
198200 @Deprecated
228230 return c;
229231 }
230232
233 @Override
231234 protected void prepareTask() {
232235 super.prepareTask();
233236 Message.setShowProgress(showProgress);
234237 }
235238
239 @Override
236240 public void doExecute() throws BuildException {
237241 Ivy ivy = getIvyInstance();
238242 IvySettings settings = ivy.getSettings();
239243 try {
240244 conf = getProperty(conf, settings, "ivy.configurations");
241245 type = getProperty(type, settings, "ivy.resolve.default.type.filter");
242 String[] confs = splitConfs(conf);
246 String[] confs = splitToArray(conf);
243247
244248 boolean childs = !dependencies.isEmpty() || !excludes.isEmpty() || !conflicts.isEmpty();
245249
266270 Ivy.getWorkingRevision());
267271 DefaultModuleDescriptor md = DefaultModuleDescriptor.newBasicInstance(mrid, null);
268272
269 Iterator itDeps = dependencies.iterator();
270 while (itDeps.hasNext()) {
271 IvyDependency dep = (IvyDependency) itDeps.next();
273 for (IvyDependency dep : dependencies) {
272274 DependencyDescriptor dd = dep.asDependencyDescriptor(md, "default", settings);
273275 md.addDependency(dd);
274276 }
275277
276 Iterator itExcludes = excludes.iterator();
277 while (itExcludes.hasNext()) {
278 IvyExclude exclude = (IvyExclude) itExcludes.next();
278 for (IvyExclude exclude : excludes) {
279279 DefaultExcludeRule rule = exclude.asRule(settings);
280280 rule.addConfiguration("default");
281281 md.addExcludeRule(rule);
282282 }
283283
284 Iterator itConflicts = conflicts.iterator();
285 while (itConflicts.hasNext()) {
286 IvyConflict conflict = (IvyConflict) itConflicts.next();
284 for (IvyConflict conflict : conflicts) {
287285 conflict.addConflict(md, settings);
288286 }
289287
353351 settings.setVariable("ivy.module", mdName);
354352 getProject().setProperty("ivy.revision", mdRev);
355353 settings.setVariable("ivy.revision", mdRev);
356 for (int i = 0; i < md.getInheritedDescriptors().length; i++) {
357 ExtendsDescriptor parent = md.getInheritedDescriptors()[i];
354 List<ExtendsDescriptor> parents = Arrays.asList(md.getInheritedDescriptors());
355 for (ExtendsDescriptor parent : parents) {
356 int i = parents.indexOf(parent);
358357 String parentOrg = parent.getResolvedParentRevisionId().getOrganisation();
359358 String parentModule = parent.getResolvedParentRevisionId().getName();
360359 String parentRevision = parent.getResolvedParentRevisionId().getRevision();
377376
378377 Boolean hasChanged = null;
379378 if (getCheckIfChanged()) {
380 hasChanged = Boolean.valueOf(report.hasChanged());
379 hasChanged = report.hasChanged();
381380 getProject().setProperty("ivy.deps.changed", hasChanged.toString());
382381 settings.setVariable("ivy.deps.changed", hasChanged.toString());
383382 }
425424 }
426425 }
427426
428 protected Collection/* <String> */getAllowedLogOptions() {
429 return Arrays.asList(new String[] {LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY,
430 LogOptions.LOG_QUIET});
427 protected Collection<String> getAllowedLogOptions() {
428 return Arrays.asList(LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY,
429 LogOptions.LOG_QUIET);
431430 }
432431
433432 private ResolveOptions getResolveOptions(Ivy ivy, String[] confs, IvySettings settings) {
475474 }
476475
477476 public boolean isKeep() {
478 return keep == null ? organisation == null : keep.booleanValue();
477 return (keep == null) ? organisation == null : keep;
479478 }
480479
481480 public void setKeep(boolean keep) {
482 this.keep = Boolean.valueOf(keep);
481 this.keep = keep;
483482 }
484483
485484 public boolean isInline() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import org.apache.tools.ant.Location;
2727 import org.apache.tools.ant.Project;
2828 import org.apache.tools.ant.types.Reference;
29 import org.apache.tools.ant.types.Resource;
2930 import org.apache.tools.ant.types.ResourceCollection;
3031 import org.apache.tools.ant.types.resources.BaseResourceCollectionWrapper;
3132 import org.apache.tools.ant.types.resources.FileResource;
3738 */
3839 private class IvyBaseResourceCollectionWrapper extends BaseResourceCollectionWrapper {
3940
40 protected Collection getCollection() {
41 protected Collection<Resource> getCollection() {
4142 return resolveResources(null);
4243 }
4344
8081 return true;
8182 }
8283
83 public Iterator iterator() {
84 public Iterator<Resource> iterator() {
8485 return wrapper.iterator();
8586 }
8687
9091
9192 // convert the ivy reports into an Ant Resource collection
9293
93 private Collection resolveResources(String id) throws BuildException {
94 private Collection<Resource> resolveResources(String id) throws BuildException {
9495 prepareAndCheck();
9596 try {
96 List/* <FileResource> */resources = new ArrayList();
97 List<Resource> resources = new ArrayList<>();
9798 if (id != null) {
9899 getProject().addReference(id, this);
99100 }
100 for (Iterator iter = getArtifactReports().iterator(); iter.hasNext();) {
101 ArtifactDownloadReport a = (ArtifactDownloadReport) iter.next();
102 resources.add(new FileResource(a.getLocalFile()));
101 for (ArtifactDownloadReport adr : getArtifactReports()) {
102 resources.add(new FileResource(adr.getLocalFile()));
103103 }
104104 return resources;
105105 } catch (Exception ex) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.util.Arrays;
2121 import java.util.Collection;
22 import java.util.Iterator;
2322
2423 import org.apache.ivy.core.LogOptions;
24 import org.apache.ivy.core.module.descriptor.Artifact;
2525 import org.apache.ivy.core.retrieve.RetrieveOptions;
2626 import org.apache.ivy.core.retrieve.RetrieveReport;
2727 import org.apache.ivy.util.filter.Filter;
3232 import org.apache.tools.ant.types.PatternSet;
3333 import org.apache.tools.ant.util.FileNameMapper;
3434
35 import static org.apache.ivy.util.StringUtils.splitToArray;
36
3537 /**
3638 * This task allow to retrieve dependencies from the cache to a local directory like a lib dir.
3739 */
3840 public class IvyRetrieve extends IvyPostResolveTask {
3941
40 private static final Collection OVERWRITEMODE_VALUES = Arrays.asList(new String[] {
41 RetrieveOptions.OVERWRITEMODE_ALWAYS, RetrieveOptions.OVERWRITEMODE_NEVER,
42 RetrieveOptions.OVERWRITEMODE_NEWER, RetrieveOptions.OVERWRITEMODE_DIFFERENT});
42 private static final Collection<String> OVERWRITEMODE_VALUES = Arrays.asList(
43 RetrieveOptions.OVERWRITEMODE_ALWAYS, RetrieveOptions.OVERWRITEMODE_NEVER,
44 RetrieveOptions.OVERWRITEMODE_NEWER, RetrieveOptions.OVERWRITEMODE_DIFFERENT);
4345
4446 private String pattern;
4547
8385 this.setId = setId;
8486 }
8587
88 @SuppressWarnings("deprecation")
89 @Override
8690 public void doExecute() throws BuildException {
8791 prepareAndCheck();
8892
9397
9498 pattern = getProperty(pattern, getSettings(), "ivy.retrieve.pattern");
9599 try {
96 Filter artifactFilter = getArtifactFilter();
97 RetrieveReport report = getIvyInstance().retrieve(
98 getResolvedMrid(),
99 ((RetrieveOptions) new RetrieveOptions().setLog(getLog()))
100 .setConfs(splitConfs(getConf())).setDestArtifactPattern(pattern)
101 .setDestIvyPattern(ivypattern).setArtifactFilter(artifactFilter)
102 .setSync(sync).setOverwriteMode(getOverwriteMode())
103 .setUseOrigin(isUseOrigin()).setMakeSymlinks(symlink)
104 .setMakeSymlinksInMass(symlinkmass).setResolveId(getResolveId())
105 .setMapper(mapper == null ? null : new MapperAdapter(mapper)));
106
100 final Filter<Artifact> artifactFilter = getArtifactFilter();
101 final RetrieveOptions retrieveOptions = (RetrieveOptions) new RetrieveOptions().setLog(getLog());
102 retrieveOptions.setConfs(splitToArray(getConf())).setDestArtifactPattern(pattern)
103 .setDestIvyPattern(ivypattern).setArtifactFilter(artifactFilter)
104 .setSync(sync).setOverwriteMode(getOverwriteMode())
105 .setUseOrigin(isUseOrigin()).setMakeSymlinks(symlink)
106 .setResolveId(getResolveId())
107 .setMapper(mapper == null ? null : new MapperAdapter(mapper));
108 // only set this if the user has explicitly enabled this deprecated option
109 if (symlinkmass) {
110 retrieveOptions.setMakeSymlinksInMass(symlinkmass);
111 }
112 final RetrieveReport report = getIvyInstance().retrieve(getResolvedMrid(), retrieveOptions);
107113 int targetsCopied = report.getNbrArtifactsCopied();
108114 boolean haveTargetsBeenCopied = targetsCopied > 0;
109115 getProject().setProperty("ivy.nb.targets.copied", String.valueOf(targetsCopied));
113119 Path path = new Path(getProject());
114120 getProject().addReference(getPathId(), path);
115121
116 for (Iterator iter = report.getRetrievedFiles().iterator(); iter.hasNext();) {
117 path.createPathElement().setLocation((File) iter.next());
122 for (File file : report.getRetrievedFiles()) {
123 path.createPathElement().setLocation(file);
118124 }
119125 }
120126
125131
126132 fileset.setDir(report.getRetrieveRoot());
127133
128 for (Iterator iter = report.getRetrievedFiles().iterator(); iter.hasNext();) {
134 for (File file : report.getRetrievedFiles()) {
129135 PatternSet.NameEntry ne = fileset.createInclude();
130 ne.setName(getPath(report.getRetrieveRoot(), (File) iter.next()));
136 ne.setName(getPath(report.getRetrieveRoot(), file));
131137 }
132138 }
133139 } catch (Exception ex) {
135141 }
136142 }
137143
138 protected Collection/* <String> */getAllowedLogOptions() {
139 return Arrays.asList(new String[] {LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY,
140 LogOptions.LOG_QUIET});
144 protected Collection<String> getAllowedLogOptions() {
145 return Arrays.asList(LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY,
146 LogOptions.LOG_QUIET);
141147 }
142148
143149 public String getIvypattern() {
158164
159165 /**
160166 * Option to create symlinks instead of copying.
167 *
168 * @param symlink boolean
161169 */
162170 public void setSymlink(boolean symlink) {
163171 this.symlink = symlink;
165173
166174 /**
167175 * Option to create symlinks in one mass action, instead of separately.
168 */
176 *
177 * @param symlinkmass boolean
178 * @deprecated Starting 2.5, symlinking in mass isn't supported
179 */
180 @Deprecated
169181 public void setSymlinkmass(boolean symlinkmass) {
170182 this.symlinkmass = symlinkmass;
171183 }
184196
185197 /**
186198 * Add a mapper to convert the file names.
187 *
199 *
188200 * @param mapper
189 * a <code>Mapper</code> value.
201 * a Mapper value.
190202 */
191203 public void addMapper(Mapper mapper) {
192204 if (this.mapper != null) {
197209
198210 /**
199211 * Add a nested filenamemapper.
200 *
212 *
201213 * @param fileNameMapper
202214 * the mapper to add.
203215 */
209221
210222 /**
211223 * Returns the path of the file relative to the given base directory.
212 *
224 *
213225 * @param base
214226 * the parent directory to which the file must be evaluated.
215227 * @param file
224236 // checks if the basePath ends with the file separator (which can for instance
225237 // happen if the basePath is the root on unix)
226238 if (!absoluteBasePath.endsWith(File.separator)) {
227 beginIndex++; // skip the seperator char as well
239 beginIndex++; // skip the separator char as well
228240 }
229241
230242 return file.getAbsolutePath().substring(beginIndex);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import org.apache.ivy.core.settings.IvySettings;
2727 import org.apache.ivy.util.DateUtil;
2828 import org.apache.ivy.util.Message;
29 import org.apache.ivy.util.StringUtils;
3029 import org.apache.tools.ant.BuildException;
3130 import org.apache.tools.ant.Task;
3231 import org.apache.tools.ant.types.Reference;
32
33 import static org.apache.ivy.util.StringUtils.joinArray;
34 import static org.apache.ivy.util.StringUtils.splitToArray;
3335
3436 /**
3537 * Base class for all ivy ant tasks, deal particularly with ivy instance storage in ant project.
4244 private Reference antIvyEngineRef = null;
4345
4446 protected boolean doValidate(IvySettings ivy) {
45 if (validate != null) {
46 return validate.booleanValue();
47 }
48 return ivy.doValidate();
47 if (validate == null) {
48 return ivy.doValidate();
49 }
50 return validate;
4951 }
5052
5153 public boolean isValidate() {
52 return validate == null ? true : validate.booleanValue();
54 return validate == null || validate;
5355 }
5456
5557 public void setValidate(boolean validate) {
56 this.validate = Boolean.valueOf(validate);
58 this.validate = validate;
5759 }
5860
5961 public void setSettingsRef(Reference ref) {
7072
7173 protected Ivy getIvyInstance() {
7274 Object antIvyEngine;
73 if (antIvyEngineRef != null) {
75 if (antIvyEngineRef == null) {
76 antIvyEngine = IvyAntSettings.getDefaultInstance(this);
77 } else {
7478 antIvyEngine = antIvyEngineRef.getReferencedObject(getProject());
7579 if (!antIvyEngine.getClass().getName().equals(IvyAntSettings.class.getName())) {
7680 throw new BuildException(antIvyEngineRef.getRefId()
8286 + "Please use the same loader when defining your task, or "
8387 + "redeclare your ivy:settings in this classloader", getLocation());
8488 }
85 } else {
86 antIvyEngine = IvyAntSettings.getDefaultInstance(this);
8789 }
8890 Ivy ivy = ((IvyAntSettings) antIvyEngine).getConfiguredIvyInstance(this);
8991 AntMessageLogger.register(this, ivy);
107109
108110 protected void setResolved(ResolveReport report, String resolveId, boolean keep) {
109111 setResolved(report, keep);
110 if (resolveId != null) {
111 ModuleDescriptor md = report.getModuleDescriptor();
112 String[] confs = report.getConfigurations();
113 getProject().addReference("ivy.resolved.report." + resolveId, report);
114 getProject().addReference("ivy.resolved.descriptor." + resolveId, md);
115 getProject().addReference("ivy.resolved.configurations.ref." + resolveId, confs);
116 }
112 if (resolveId == null) {
113 return;
114 }
115 ModuleDescriptor md = report.getModuleDescriptor();
116 String[] confs = report.getConfigurations();
117 getProject().addReference("ivy.resolved.report." + resolveId, report);
118 getProject().addReference("ivy.resolved.descriptor." + resolveId, md);
119 getProject().addReference("ivy.resolved.configurations.ref." + resolveId, confs);
117120 }
118121
119122 protected String[] getResolvedConfigurations(String org, String module, boolean strict) {
120123 return (String[]) getReference("ivy.resolved.configurations.ref", org, module, strict);
121124 }
122125
123 protected Object getResolvedDescriptor(String resolveId) {
126 protected <T> T getResolvedDescriptor(String resolveId) {
124127 return getResolvedDescriptor(resolveId, true);
125128 }
126129
127 protected Object getResolvedDescriptor(String resolveId, boolean strict) {
128 Object result = getProject().getReference("ivy.resolved.descriptor." + resolveId);
129 if (strict && (result == null)) {
130 protected <T> T getResolvedDescriptor(String resolveId, boolean strict) {
131 T result = getProject().getReference("ivy.resolved.descriptor." + resolveId);
132 if (strict && result == null) {
130133 throw new BuildException("ModuleDescriptor for resolve with id '" + resolveId
131134 + "' not found.");
132135 }
133136 return result;
134137 }
135138
136 protected Object getResolvedDescriptor(String org, String module) {
139 protected <T> T getResolvedDescriptor(String org, String module) {
137140 return getResolvedDescriptor(org, module, false);
138141 }
139142
140 protected Object getResolvedDescriptor(String org, String module, boolean strict) {
143 protected <T> T getResolvedDescriptor(String org, String module, boolean strict) {
141144 return getReference("ivy.resolved.descriptor", org, module, strict);
142145 }
143146
144 private Object getReference(String prefix, String org, String module, boolean strict) {
145 Object reference = null;
147 private <T> T getReference(String prefix, String org, String module, boolean strict) {
148 T reference = null;
146149 if (org != null && module != null) {
147150 reference = getProject().getReference(prefix + "." + org + "." + module);
148151 }
153156 }
154157
155158 protected ResolveReport getResolvedReport(String org, String module, String resolveId) {
156 ResolveReport result = null;
157
158 if (resolveId == null) {
159 result = (ResolveReport) getReference("ivy.resolved.report", org, module, false);
160 } else {
161 result = (ResolveReport) getReference("ivy.resolved.report." + resolveId, null, null,
162 false);
163 }
164
165 return result;
159 if (resolveId == null) {
160 return getReference("ivy.resolved.report", org, module, false);
161 }
162 return getReference("ivy.resolved.report." + resolveId, null, null,
163 false);
166164 }
167165
168166 protected String[] splitConfs(String conf) {
169 if (conf == null) {
170 return null;
171 }
172 String[] confs = conf.split(",");
173 for (int i = 0; i < confs.length; i++) {
174 confs[i] = confs[i].trim();
175 }
176 return confs;
167 return splitToArray(conf);
177168 }
178169
179170 protected String mergeConfs(String[] conf) {
180 return StringUtils.join(conf, ", ");
171 return joinArray(conf, ", ");
181172 }
182173
183174 protected static Date getPubDate(String date, Date def) {
184 if (date != null) {
185 if ("now".equals(date.toLowerCase(Locale.US))) {
186 return new Date();
187 }
188 try {
189 return DateUtil.parse(date);
190 } catch (Exception ex) {
191 throw new BuildException("Publication date provided in bad format. Should be '"
192 + DateUtil.DATE_FORMAT_PATTERN + "' and not '" + date + "'!");
193 }
194 } else {
175 if (date == null) {
195176 return def;
177 }
178 if ("now".equals(date.toLowerCase(Locale.US))) {
179 return new Date();
180 }
181 try {
182 return DateUtil.parse(date);
183 } catch (Exception ex) {
184 throw new BuildException("Publication date provided in bad format. Should be '"
185 + DateUtil.DATE_FORMAT_PATTERN + "' and not '" + date + "'!");
196186 }
197187 }
198188
199189 protected String getProperty(String value, IvySettings ivy, String name) {
200190 if (value == null) {
201191 return getProperty(ivy, name);
202 } else {
203 value = ivy.substitute(value);
204 Message.debug("parameter found as attribute value: " + name + "=" + value);
205 return value;
206 }
192 }
193 value = ivy.substitute(value);
194 Message.debug("parameter found as attribute value: " + name + "=" + value);
195 return value;
207196 }
208197
209198 protected String getProperty(String value, IvySettings ivy, String name, String resolveId) {
210199 if (resolveId == null) {
211200 return getProperty(value, ivy, name);
212 } else {
213 return getProperty(value, ivy, name + "." + resolveId);
214 }
201 }
202 return getProperty(value, ivy, name + "." + resolveId);
215203 }
216204
217205 protected String getProperty(IvySettings ivy, String name, String resolveId) {
218206 if (resolveId == null) {
219207 return getProperty(ivy, name);
220 } else {
221 return getProperty(ivy, name + "." + resolveId);
222 }
208 }
209 return getProperty(ivy, name + "." + resolveId);
223210 }
224211
225212 protected String getProperty(IvySettings ivy, String name) {
226213 String val = ivy.getVariable(name);
227214 if (val == null) {
228215 val = ivy.substitute(getProject().getProperty(name));
229 if (val != null) {
216 if (val == null) {
217 Message.debug("parameter not found: " + name);
218 } else {
230219 Message.debug("parameter found as ant project property: " + name + "=" + val);
231 } else {
232 Message.debug("parameter not found: " + name);
233220 }
234221 } else {
235222 val = ivy.substitute(val);
256243 */
257244 protected void finalizeTask() {
258245 if (!IvyContext.getContext().pop(ANT_PROJECT_CONTEXT_KEY, getProject())) {
259 Message.error("ANT project poped from stack not equals current !. Ignoring");
246 Message.error("ANT project popped from stack not equals current! Ignoring");
260247 }
261248 IvyContext.popContext();
262249 }
263250
264251 /**
265 * Ant task execute. Calls prepareTask, doExecute, finalzeTask
266 */
252 * Ant task execute. Calls prepareTask, doExecute, finalizeTask
253 */
254 @Override
267255 public final void execute() throws BuildException {
268256 try {
269257 prepareTask();
276264 /**
277265 * The real logic of task execution after project has been set in the context. MUST be
278266 * implemented by subclasses
279 *
280 * @throws BuildException
267 *
268 * @throws BuildException if something goes wrong
281269 */
282270 public abstract void doExecute() throws BuildException;
283271
272 @Override
284273 public String toString() {
285274 return getClass().getName() + ":" + getTaskName();
286275 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.io.FileInputStream;
2121 import java.io.InputStream;
2222 import java.net.URL;
23 import java.util.Iterator;
23 import java.util.Map;
2424 import java.util.Properties;
2525
2626 import org.apache.ivy.Ivy;
109109 }
110110 }
111111 }
112 for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
113 String name = (String) iter.next();
114 String value = (String) props.get(name);
115 settings.setVariable(getVarName(name), value);
112 for (Map.Entry<Object, Object> entry : props.entrySet()) {
113 settings.setVariable(getVarName((String) entry.getKey()), (String) entry.getValue());
116114 }
117115 }
118116 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.ivy.core.module.id.ModuleRevisionId;
2020
2121 /**
22 * Describes a mapping between a package name and an org name revision uple
22 * Describes a mapping between a package name and an org name revision tuple
2323 */
2424 public class PackageMapping {
2525 private String pkg;
5858 return pkg;
5959 }
6060
61 public void setPackage(String package1) {
62 pkg = package1;
61 public void setPackage(String packageName) {
62 pkg = packageName;
6363 }
6464
6565 public ModuleRevisionId getModuleRevisionId() {
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
1919 <antlib xmlns:current="ant:current">
2020 <typedef name="settings" classname="org.apache.ivy.ant.IvyAntSettings"/>
2121 <typedef name="resources" classname="org.apache.ivy.ant.IvyResources" onerror="report"/>
22 <taskdef name="configure" classname="org.apache.ivy.ant.IvyConfigure"/>
23 <taskdef name="resolve" classname="org.apache.ivy.ant.IvyResolve"/>
24 <taskdef name="retrieve" classname="org.apache.ivy.ant.IvyRetrieve"/>
25 <taskdef name="deliver" classname="org.apache.ivy.ant.IvyDeliver"/>
26 <taskdef name="publish" classname="org.apache.ivy.ant.IvyPublish"/>
27 <taskdef name="extract" classname="org.apache.ivy.ant.IvyExtractFromSources"/>
28 <taskdef name="cachepath" classname="org.apache.ivy.ant.IvyCachePath"/>
29 <taskdef name="cachefileset" classname="org.apache.ivy.ant.IvyCacheFileset"/>
30 <taskdef name="report" classname="org.apache.ivy.ant.IvyReport"/>
31 <taskdef name="repreport" classname="org.apache.ivy.ant.IvyRepositoryReport"/>
32 <taskdef name="var" classname="org.apache.ivy.ant.IvyVar"/>
33 <taskdef name="check" classname="org.apache.ivy.ant.IvyCheck"/>
34 <taskdef name="artifactproperty" classname="org.apache.ivy.ant.IvyArtifactProperty"/>
35 <taskdef name="buildlist" classname="org.apache.ivy.ant.IvyBuildList"/>
36 <taskdef name="install" classname="org.apache.ivy.ant.IvyInstall"/>
37 <taskdef name="convertpom" classname="org.apache.ivy.ant.IvyConvertPom"/>
38 <taskdef name="makepom" classname="org.apache.ivy.ant.IvyMakePom"/>
39 <taskdef name="artifactreport" classname="org.apache.ivy.ant.IvyArtifactReport"/>
40 <taskdef name="info" classname="org.apache.ivy.ant.IvyInfo"/>
41 <taskdef name="addpath" classname="org.apache.ivy.ant.AddPathTask"/>
42 <taskdef name="listmodules" classname="org.apache.ivy.ant.IvyListModules"/>
43 <taskdef name="findrevision" classname="org.apache.ivy.ant.IvyFindRevision"/>
44 <taskdef name="buildnumber" classname="org.apache.ivy.ant.IvyBuildNumber"/>
45 <taskdef name="cleancache" classname="org.apache.ivy.ant.IvyCleanCache"/>
46 <taskdef name="buildobr" classname="org.apache.ivy.ant.BuildOBRTask" />
47 <taskdef name="convertmanifest" classname="org.apache.ivy.ant.ConvertManifestTask" />
48 <taskdef name="fixdeps" classname="org.apache.ivy.ant.FixDepsTask" />
22 <taskdef name="configure" classname="org.apache.ivy.ant.IvyConfigure"/>
23 <taskdef name="resolve" classname="org.apache.ivy.ant.IvyResolve"/>
24 <taskdef name="retrieve" classname="org.apache.ivy.ant.IvyRetrieve"/>
25 <taskdef name="deliver" classname="org.apache.ivy.ant.IvyDeliver"/>
26 <taskdef name="publish" classname="org.apache.ivy.ant.IvyPublish"/>
27 <taskdef name="extract" classname="org.apache.ivy.ant.IvyExtractFromSources"/>
28 <taskdef name="cachepath" classname="org.apache.ivy.ant.IvyCachePath"/>
29 <taskdef name="cachefileset" classname="org.apache.ivy.ant.IvyCacheFileset"/>
30 <taskdef name="report" classname="org.apache.ivy.ant.IvyReport"/>
31 <taskdef name="repreport" classname="org.apache.ivy.ant.IvyRepositoryReport"/>
32 <taskdef name="var" classname="org.apache.ivy.ant.IvyVar"/>
33 <taskdef name="check" classname="org.apache.ivy.ant.IvyCheck"/>
34 <taskdef name="artifactproperty" classname="org.apache.ivy.ant.IvyArtifactProperty"/>
35 <taskdef name="buildlist" classname="org.apache.ivy.ant.IvyBuildList"/>
36 <taskdef name="install" classname="org.apache.ivy.ant.IvyInstall"/>
37 <taskdef name="convertpom" classname="org.apache.ivy.ant.IvyConvertPom"/>
38 <taskdef name="makepom" classname="org.apache.ivy.ant.IvyMakePom"/>
39 <taskdef name="artifactreport" classname="org.apache.ivy.ant.IvyArtifactReport"/>
40 <taskdef name="info" classname="org.apache.ivy.ant.IvyInfo"/>
41 <taskdef name="addpath" classname="org.apache.ivy.ant.AddPathTask"/>
42 <taskdef name="listmodules" classname="org.apache.ivy.ant.IvyListModules"/>
43 <taskdef name="findrevision" classname="org.apache.ivy.ant.IvyFindRevision"/>
44 <taskdef name="buildnumber" classname="org.apache.ivy.ant.IvyBuildNumber"/>
45 <taskdef name="cleancache" classname="org.apache.ivy.ant.IvyCleanCache"/>
46 <taskdef name="buildobr" classname="org.apache.ivy.ant.BuildOBRTask"/>
47 <taskdef name="convertmanifest" classname="org.apache.ivy.ant.ConvertManifestTask"/>
48 <taskdef name="fixdeps" classname="org.apache.ivy.ant.FixDepsTask"/>
4949 <taskdef name="dependencytree" classname="org.apache.ivy.ant.IvyDependencyTree"/>
5050 <taskdef name="checkdepsupdate" classname="org.apache.ivy.ant.IvyDependencyUpdateChecker"/>
51 <typedef name="workspaceresolver" classname="org.apache.ivy.ant.AntWorkspaceResolver"/>
5152 </antlib>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535 /**
3636 * This class represents an execution context of an Ivy action. It contains several getters to
3737 * retrieve information, like the used Ivy instance, the cache location...
38 *
38 *
3939 * @see IvyThread
4040 */
4141 public class IvyContext {
4242
43 private static ThreadLocal/* <Stack<IvyContext>> */current = new ThreadLocal();
43 private static ThreadLocal<Stack<IvyContext>> current = new ThreadLocal<>();
4444
4545 private Ivy defaultIvy;
4646
47 private WeakReference/* <Ivy> */ivy = new WeakReference(null);
48
49 private Map contextMap = new HashMap();
47 private WeakReference<Ivy> ivy = new WeakReference<>(null);
48
49 private Map<String, Object> contextMap = new HashMap<>();
5050
5151 private Thread operatingThread;
5252
6060 public IvyContext(IvyContext ctx) {
6161 defaultIvy = ctx.defaultIvy;
6262 ivy = ctx.ivy;
63 contextMap = new HashMap(ctx.contextMap);
63 contextMap = new HashMap<>(ctx.contextMap);
6464 operatingThread = ctx.operatingThread;
6565 resolveData = ctx.resolveData;
6666 dd = ctx.dd;
6767 }
6868
6969 public static IvyContext getContext() {
70 Stack cur = getCurrentStack();
70 Stack<IvyContext> cur = getCurrentStack();
7171 if (cur.isEmpty()) {
7272 cur.push(new IvyContext());
7373 }
74 return (IvyContext) cur.peek();
75 }
76
77 private static Stack/* <IvyContext> */getCurrentStack() {
78 Stack cur = (Stack) current.get();
74 return cur.peek();
75 }
76
77 private static Stack<IvyContext> getCurrentStack() {
78 Stack<IvyContext> cur = current.get();
7979 if (cur == null) {
80 cur = new Stack();
80 cur = new Stack<>();
8181 current.set(cur);
8282 }
8383 return cur;
8989 * {@link #popContext()} should usually be called when the job for which this context has been
9090 * pushed is finished.
9191 * </p>
92 *
92 *
9393 * @return the newly pushed context
9494 */
9595 public static IvyContext pushNewContext() {
103103 * {@link #popContext()} should usually be called when the job for which this context has been
104104 * pushed is finished.
105105 * </p>
106 *
106 *
107107 * @return the newly pushed context
108108 */
109109 public static IvyContext pushNewCopyContext() {
114114 * Changes the context associated with this thread. This is especially useful when launching a
115115 * new thread, to associate it with the same context as the initial one. Do not forget to call
116116 * {@link #popContext()} when done.
117 *
117 *
118118 * @param context
119119 * the new context to use in this thread.
120120 * @return the pushed context
128128 * Pops one context used with this thread. This is usually called after having finished a task
129129 * for which a call to {@link #pushNewContext()} or {@link #pushContext(IvyContext)} was done
130130 * prior to beginning the task.
131 *
131 *
132132 * @return the popped context
133133 */
134134 public static IvyContext popContext() {
135 return (IvyContext) getCurrentStack().pop();
135 return getCurrentStack().pop();
136136 }
137137
138138 /**
143143 * This methods does a similar job to {@link #peek(String)}, except that it considers the whole
144144 * context stack and not only one instance.
145145 * </p>
146 *
146 *
147147 * @param key
148148 * context key for the string
149149 * @return top object from the list (index 0) of the first context in the stack containing this
152152 */
153153 public static Object peekInContextStack(String key) {
154154 Object value = null;
155 Stack contextStack = getCurrentStack();
155 Stack<IvyContext> contextStack = getCurrentStack();
156156 for (int i = contextStack.size() - 1; i >= 0 && value == null; i--) {
157 IvyContext ctx = (IvyContext) contextStack.get(i);
157 IvyContext ctx = contextStack.get(i);
158158 value = ctx.peek(key);
159159 }
160160 return value;
171171 * Then, or if no ivy method has been called, a default ivy instance is returned by this method,
172172 * so that it never returns <code>null</code>.
173173 * </p>
174 *
174 *
175175 * @return the current ivy instance
176176 */
177177 public Ivy getIvy() {
186186 * If you want get a default Ivy instance in case no instance if currently associated, use
187187 * {@link #getIvy()}.
188188 * </p>
189 *
189 *
190190 * @return the current ivy instance, or <code>null</code> if there is no current ivy instance.
191191 */
192192 public Ivy peekIvy() {
193 Ivy ivy = (Ivy) this.ivy.get();
194 return ivy;
193 return this.ivy.get();
195194 }
196195
197196 private Ivy getDefaultIvy() {
208207 }
209208
210209 public void setIvy(Ivy ivy) {
211 this.ivy = new WeakReference(ivy);
210 this.ivy = new WeakReference<>(ivy);
212211 operatingThread = Thread.currentThread();
213212 }
214213
220219 return getSettings().getCircularDependencyStrategy();
221220 }
222221
223 public Object get(String key) {
224 WeakReference ref = (WeakReference) contextMap.get(key);
225 return ref == null ? null : ref.get();
226 }
227
228 public void set(String key, Object value) {
229 contextMap.put(key, new WeakReference(value));
222 @SuppressWarnings("unchecked")
223 public <T> T get(String key) {
224 WeakReference<T> ref = (WeakReference<T>) contextMap.get(key);
225 return (ref == null) ? null : ref.get();
226 }
227
228 public <T> void set(String key, T value) {
229 contextMap.put(key, new WeakReference<>(value));
230230 }
231231
232232 /**
233233 * Reads the first object from the list saved under given key in the context. If value under key
234234 * represents non List object then a RuntimeException is thrown.
235 *
235 *
236236 * @param key
237237 * context key for the string
238238 * @return top object from the list (index 0) or null if no key or list empty
239239 */
240 @SuppressWarnings("unchecked")
240241 public Object peek(String key) {
241242 synchronized (contextMap) {
242243 Object o = contextMap.get(key);
244245 return null;
245246 }
246247 if (o instanceof List) {
247 if (((List) o).size() == 0) {
248 if (((List<Object>) o).size() == 0) {
248249 return null;
249250 }
250 Object ret = ((List) o).get(0);
251 return ret;
251 return ((List<Object>) o).get(0);
252252 } else {
253253 throw new RuntimeException("Cannot top from non List object " + o);
254254 }
258258 /**
259259 * Removes and returns first object from the list saved under given key in the context. If value
260260 * under key represents non List object then a RuntimeException is thrown.
261 *
261 *
262262 * @param key
263263 * context key for the string
264264 * @return top object from the list (index 0) or null if no key or list empty
265265 */
266 @SuppressWarnings("unchecked")
266267 public Object pop(String key) {
267268 synchronized (contextMap) {
268269 Object o = contextMap.get(key);
270271 return null;
271272 }
272273 if (o instanceof List) {
273 if (((List) o).size() == 0) {
274 if (((List<Object>) o).size() == 0) {
274275 return null;
275276 }
276 Object ret = ((List) o).remove(0);
277 return ret;
277 return ((List<Object>) o).remove(0);
278278 } else {
279279 throw new RuntimeException("Cannot pop from non List object " + o);
280280 }
285285 * Removes and returns first object from the list saved under given key in the context but only
286286 * if it equals the given expectedValue - if not a false value is returned. If value under key
287287 * represents non List object then a RuntimeException is thrown.
288 *
288 *
289289 * @param key
290290 * context key for the string
291 * @param expectedValue
292 * expected value of the key
291293 * @return true if the r
292294 */
295 @SuppressWarnings("unchecked")
293296 public boolean pop(String key, Object expectedValue) {
294297 synchronized (contextMap) {
295298 Object o = contextMap.get(key);
297300 return false;
298301 }
299302 if (o instanceof List) {
300 if (((List) o).size() == 0) {
303 if (((List<Object>) o).size() == 0) {
301304 return false;
302305 }
303 Object top = ((List) o).get(0);
306 Object top = ((List<Object>) o).get(0);
304307 if (!top.equals(expectedValue)) {
305308 return false;
306309 }
307 ((List) o).remove(0);
310 ((List<Object>) o).remove(0);
308311 return true;
309312 } else {
310313 throw new RuntimeException("Cannot pop from non List object " + o);
317320 * under key represents non List object then a RuntimeException is thrown. If no list exists
318321 * under given key a new LinkedList is created. This is kept without WeakReference in opposite
319322 * to the put() results.
320 *
323 *
321324 * @param key
322325 * key context key for the string
323326 * @param value
324327 * value to be saved under the key
325328 */
329 @SuppressWarnings("unchecked")
326330 public void push(String key, Object value) {
327331 synchronized (contextMap) {
328332 if (!contextMap.containsKey(key)) {
329 contextMap.put(key, new LinkedList());
333 contextMap.put(key, new LinkedList<>());
330334 }
331335 Object o = contextMap.get(key);
332336 if (o instanceof List) {
333 ((List) o).add(0, value);
337 ((List<Object>) o).add(0, value);
334338 } else {
335339 throw new RuntimeException("Cannot push to non List object " + o);
336340 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.List;
2322 import java.util.Map;
2423 import java.util.Stack;
3433 import org.apache.ivy.core.settings.IvyVariableContainerImpl;
3534 import org.apache.ivy.util.Message;
3635
36 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
37
3738 /**
3839 */
3940 public final class IvyPatternHelper {
8586 }
8687
8788 public static String substitute(String pattern, Artifact artifact, ArtifactOrigin origin) {
88 return substitute(pattern, artifact.getModuleRevisionId(), artifact, (String) null, origin);
89 return substitute(pattern, artifact.getModuleRevisionId(), artifact, null, origin);
8990 }
9091
9192 public static String substitute(String pattern, Artifact artifact, String conf) {
92 return substitute(pattern, artifact.getModuleRevisionId(), artifact, conf,
93 (ArtifactOrigin) null);
93 return substitute(pattern, artifact.getModuleRevisionId(), artifact, conf, null);
9494 }
9595
9696 public static String substitute(String pattern, ModuleRevisionId mrid, Artifact artifact) {
97 return substitute(pattern, mrid, artifact, (String) null, (ArtifactOrigin) null);
97 return substitute(pattern, mrid, artifact, null, null);
9898 }
9999
100100 public static String substitute(String pattern, ModuleRevisionId mrid, Artifact artifact,
106106
107107 public static String substitute(String pattern, String org, String module, String revision,
108108 String artifact, String type, String ext) {
109 return substitute(pattern, org, module, (String) null, revision, artifact, type, ext,
110 (String) null, (ArtifactOrigin) null, (Map) null, (Map) null);
109 return substitute(pattern, org, module, null, revision, artifact, type, ext,
110 null, null, null, null);
111111 }
112112
113113 // CheckStyle:ParameterNumber OFF
114114 public static String substitute(String pattern, String org, String module, String revision,
115115 String artifact, String type, String ext, String conf) {
116 return substitute(pattern, org, module, (String) null, revision, artifact, type, ext, conf,
117 (ArtifactOrigin) null, (Map) null, (Map) null);
116 return substitute(pattern, org, module, null, revision, artifact, type, ext, conf,
117 null, null, null);
118118 }
119119
120120 public static String substitute(String pattern, String org, String module, String revision,
121 String artifact, String type, String ext, String conf, Map extraModuleAttributes,
122 Map extraArtifactAttributes) {
123 return substitute(pattern, org, module, (String) null, revision, artifact, type, ext, conf,
124 (ArtifactOrigin) null, extraModuleAttributes, extraArtifactAttributes);
121 String artifact, String type, String ext, String conf, Map<String, String> extraModuleAttributes,
122 Map<String, String> extraArtifactAttributes) {
123 return substitute(pattern, org, module, null, revision, artifact, type, ext, conf,
124 null, extraModuleAttributes, extraArtifactAttributes);
125125 }
126126
127127 public static String substitute(String pattern, String org, String module, String branch,
128128 String revision, String artifact, String type, String ext, String conf,
129 ArtifactOrigin origin, Map extraModuleAttributes, Map extraArtifactAttributes) {
130 Map tokens = new HashMap();
129 ArtifactOrigin origin, Map<String, String> extraModuleAttributes, Map<String, String> extraArtifactAttributes) {
130 Map<String, Object> tokens = new HashMap<>();
131131 if (extraModuleAttributes != null) {
132 for (Iterator entries = extraModuleAttributes.entrySet().iterator(); entries.hasNext();) {
133 Map.Entry entry = (Map.Entry) entries.next();
134 String token = (String) entry.getKey();
132 for (Map.Entry<String, String> entry : extraModuleAttributes.entrySet()) {
133 String token = entry.getKey();
135134 if (token.indexOf(':') > 0) {
136135 token = token.substring(token.indexOf(':') + 1);
137136 }
139138 }
140139 }
141140 if (extraArtifactAttributes != null) {
142 for (Iterator entries = extraArtifactAttributes.entrySet().iterator(); entries
143 .hasNext();) {
144 Map.Entry entry = (Map.Entry) entries.next();
145 String token = (String) entry.getKey();
141 for (Map.Entry<String, String> entry : extraArtifactAttributes.entrySet()) {
142 String token = entry.getKey();
146143 if (token.indexOf(':') > 0) {
147144 token = token.substring(token.indexOf(':') + 1);
148145 }
167164 tokens.put(ORIGINAL_ARTIFACTNAME_KEY, new OriginalArtifactNameValue(origin));
168165 }
169166
170 return substituteTokens(pattern, tokens);
167 return substituteTokens(pattern, tokens, false);
171168 }
172169
173170 // CheckStyle:ParameterNumber ON
174171
175 public static String substituteVariables(String pattern, Map variables) {
176 return substituteVariables(pattern, new IvyVariableContainerImpl(variables), new Stack());
172 public static String substituteVariables(String pattern, Map<String, String> variables) {
173 return substituteVariables(pattern, new IvyVariableContainerImpl(variables), new Stack<String>());
177174 }
178175
179176 public static String substituteVariables(String pattern, IvyVariableContainer variables) {
180 return substituteVariables(pattern, variables, new Stack());
177 return substituteVariables(pattern, variables, new Stack<String>());
181178 }
182179
183180 private static String substituteVariables(String pattern, IvyVariableContainer variables,
184 Stack substituting) {
181 Stack<String> substituting) {
185182 // if you supply null, null is what you get
186183 if (pattern == null) {
187184 return null;
201198 if (val != null) {
202199 int index = substituting.indexOf(var);
203200 if (index != -1) {
204 List cycle = new ArrayList(substituting.subList(index, substituting.size()));
201 List<String> cycle = new ArrayList<>(substituting.subList(index, substituting.size()));
205202 cycle.add(var);
206203 throw new IllegalArgumentException("cyclic variable definition: cycle = "
207204 + cycle);
222219 }
223220 }
224221
225 public static String substituteTokens(String pattern, Map tokens) {
226 Map tokensCopy = new HashMap(tokens);
222 // This is a cludge to reconcile different values passed to the method
223 public static String substituteTokens(String pattern, Map<String, String> tokens) {
224 Map<String, Object> tokensCopy = new HashMap<>();
225 tokensCopy.putAll(tokens);
226 return substituteTokens(pattern, tokensCopy, true);
227 }
228
229 private static String substituteTokens(String pattern, Map<String, Object> tokens, boolean external) {
230 Map<String, Object> tokensCopy = external ? tokens : new HashMap<>(tokens);
227231 if (tokensCopy.containsKey(ORGANISATION_KEY) && !tokensCopy.containsKey(ORGANISATION_KEY2)) {
228232 tokensCopy.put(ORGANISATION_KEY2, tokensCopy.get(ORGANISATION_KEY));
229233 }
233237 tokensCopy.put(ORGANISATION_PATH_KEY, org == null ? "" : org.replace('.', '/'));
234238 }
235239
236 StringBuffer buffer = new StringBuffer();
237
238 char[] chars = pattern.toCharArray();
240 StringBuilder buffer = new StringBuilder();
239241
240242 StringBuffer optionalPart = null;
241243 StringBuffer tokenBuffer = null;
244246 boolean tokenSeen = false;
245247 boolean tokenHadValue = false;
246248
247 for (int i = 0; i < chars.length; i++) {
248 switch (chars[i]) {
249 for (char ch : pattern.toCharArray()) {
250 int i = pattern.indexOf(ch);
251 switch (ch) {
249252 case '(':
250253 if (insideOptionalPart) {
251254 throw new IllegalArgumentException(
258261 tokenSeen = false;
259262 tokenHadValue = false;
260263 break;
261
262264 case ')':
263265 if (!insideOptionalPart || insideToken) {
264266 throw new IllegalArgumentException(
271273 } else if (!tokenSeen) {
272274 buffer.append('(').append(optionalPart.toString()).append(')');
273275 }
274
275276 insideOptionalPart = false;
276277 break;
277
278278 case '[':
279279 if (insideToken) {
280280 throw new IllegalArgumentException("invalid start of token at position "
284284 tokenBuffer = new StringBuffer();
285285 insideToken = true;
286286 break;
287
288287 case ']':
289288 if (!insideToken) {
290289 throw new IllegalArgumentException("invalid end of token at position " + i
294293 String token = tokenBuffer.toString();
295294 Object tokenValue = tokensCopy.get(token);
296295 String value = (tokenValue == null) ? null : tokenValue.toString();
297
298296 if (insideOptionalPart) {
299 tokenHadValue = (value != null) && (value.length() > 0);
297 tokenHadValue = !isNullOrEmpty(value);
300298 optionalPart.append(value);
301299 } else {
302300 if (value == null) { // the token wasn't set, it's kept as is
304302 }
305303 buffer.append(value);
306304 }
307
308305 insideToken = false;
309306 tokenSeen = true;
310307 break;
311
312308 default:
313309 if (insideToken) {
314 tokenBuffer.append(chars[i]);
310 tokenBuffer.append(ch);
315311 } else if (insideOptionalPart) {
316 optionalPart.append(chars[i]);
312 optionalPart.append(ch);
317313 } else {
318 buffer.append(chars[i]);
319 }
320
314 buffer.append(ch);
315 }
321316 break;
322317 }
323318 }
367362 return "[" + token + "]";
368363 }
369364
370 public static String substituteParams(String pattern, Map params) {
371 return substituteParams(pattern, new IvyVariableContainerImpl(params), new Stack());
365 public static String substituteParams(String pattern, Map<String, String> params) {
366 return substituteParams(pattern, new IvyVariableContainerImpl(params), new Stack<String>());
372367 }
373368
374369 private static String substituteParams(String pattern, IvyVariableContainer params,
375 Stack substituting) {
370 Stack<String> substituting) {
376371 // TODO : refactor this with substituteVariables
377372 // if you supply null, null is what you get
378373 if (pattern == null) {
388383 if (val != null) {
389384 int index = substituting.indexOf(var);
390385 if (index != -1) {
391 List cycle = new ArrayList(substituting.subList(index, substituting.size()));
386 List<String> cycle = new ArrayList<>(substituting.subList(index, substituting.size()));
392387 cycle.add(var);
393388 throw new IllegalArgumentException("cyclic param definition: cycle = " + cycle);
394389 }
420415
421416 private String revision;
422417
423 private Map extraModuleAttributes;
418 private Map<String, String> extraModuleAttributes;
424419
425420 // artifact properties
426421 private String artifactName;
429424
430425 private String artifactExt;
431426
432 private Map extraArtifactAttributes;
427 private Map<String, String> extraArtifactAttributes;
433428
434429 // cached origin;
435430 private ArtifactOrigin origin;
436431
437432 public OriginalArtifactNameValue(String org, String moduleName, String branch,
438433 String revision, String artifactName, String artifactType, String artifactExt,
439 Map extraModuleAttributes, Map extraArtifactAttributes) {
434 Map<String, String> extraModuleAttributes, Map<String, String> extraArtifactAttributes) {
440435 this.org = org;
441436 this.moduleName = moduleName;
442437 this.branch = branch;
449444 }
450445
451446 /**
452 * @param origin
447 * @param origin ArtifactOrigin
453448 */
454449 public OriginalArtifactNameValue(ArtifactOrigin origin) {
455450 this.origin = origin;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 /**
2020 * A simple thread subclass associated the same IvyContext as the thread in which it is
21 * instanciated. If you override the run target, then you will have to call initContext() to do the
21 * instantiated. If you override the run target, then you will have to call initContext() to do the
2222 * association with the original IvyContext.
23 *
23 *
2424 * @see IvyContext
2525 */
2626 public class IvyThread extends Thread {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727
2828 /**
2929 * Resolve the url in the context of context.
30 *
30 *
3131 * @param context
32 * The URL of the ressource containing the reference url
32 * The URL of the resource containing the reference url
3333 * @param url
3434 * a relative or absolution url string
35 * @throws MalformedURLException
35 * @return URL
36 * @throws MalformedURLException if url is wrong
3637 */
3738 public abstract URL getURL(URL context, String url) throws MalformedURLException;
3839
3940 /**
40 * Relsovle file or url path relatively to a context. file is considered first. If file is not
41 * Resolve file or url path relatively to a context. file is considered first. If file is not
4142 * defined, url will be considered.
42 *
43 *
4344 * @param context
44 * The URL of the ressource containing the reference file or url
45 * The URL of the resource containing the reference file or url
4546 * @param file
4647 * a relative or absolute path
4748 * @param url
4849 * a relative or absolution url string
49 * @return the resulting url or null if faile and url are null.
50 * @throws MalformedURLException
50 * @return the resulting url or null if failed and url are null.
51 * @throws MalformedURLException if url is wrong
5152 */
5253 public URL getURL(URL context, String file, String url) throws MalformedURLException {
5354 if (file != null) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 /**
2323 * This class contains information about the origin of an artifact.
24 *
24 *
2525 * @see org.apache.ivy.plugins.resolver.BasicResolver
2626 * @see org.apache.ivy.plugins.resolver.util.ResolvedResource
2727 */
2929 private static final String UNKNOWN = "UNKNOWN";
3030
3131 /**
32 * @param artifact ditto
33 * @return ArtifactOrigin
34 * @deprecated because of renaming due spell check.
35 */
36 @Deprecated
37 public static final ArtifactOrigin unkwnown(Artifact artifact) {
38 return unknown(artifact);
39 }
40
41 /**
3242 * ArtifactOrigin instance used when the origin is unknown.
43 *
44 * @param artifact ditto
45 * @return ArtifactOrigin
3346 */
34 public static final ArtifactOrigin unkwnown(Artifact artifact) {
47 public static final ArtifactOrigin unknown(Artifact artifact) {
3548 return new ArtifactOrigin(artifact, false, UNKNOWN);
3649 }
3750
5770
5871 /**
5972 * Create a new instance
60 *
73 *
6174 * @param artifact
6275 * the artifact pointed by this location. Must not be <code>null</code>.
6376 * @param isLocal
7689
7790 /**
7891 * Is this resource local to this host, i.e. is it on the file system?
79 *
92 *
8093 * @return <code>boolean</code> value indicating if the resource is local.
8194 */
8295 public boolean isLocal() {
8598
8699 /**
87100 * Return the location of the resource (normally a url)
88 *
101 *
89102 * @return the location of the resource
90103 */
91104 public String getLocation() {
98111
99112 /**
100113 * Return the artifact that this location is pointing at.
101 *
114 *
102115 * @return the artifact that this location is pointing at.
103116 */
104117 public Artifact getArtifact() {
108121 /**
109122 * The last time the resource was checked to be up to date. Maybe <code>null</code> if this
110123 * information is not actually used by in some case.
111 *
112 * @return
124 *
125 * @return Long timestamp
113126 */
114127 public Long getLastChecked() {
115128 return lastChecked;
136149 if (this == o) {
137150 return true;
138151 }
139 if (o == null || getClass() != o.getClass()) {
152 if (!(o instanceof ArtifactOrigin)) {
140153 return false;
141154 }
142155
143156 ArtifactOrigin that = (ArtifactOrigin) o;
144157
145 if (isLocal != that.isLocal) {
146 return false;
147 }
148 if (!location.equals(that.location)) {
158 if (isLocal != that.isLocal || !location.equals(that.location)) {
149159 return false;
150160 }
151161 if (lastChecked == null) {
155165 } else if (!lastChecked.equals(that.lastChecked)) {
156166 return false;
157167 }
158 if (exists != that.exists) {
159 return false;
160 }
161168
162 return true;
169 return exists == that.exists;
163170 }
164171
165172 public int hashCode() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030 private String changingPattern = null;
3131
3232 private boolean checkTTL = true;
33
34 private boolean useCacheOnly = false;
3335
3436 public Namespace getNamespace() {
3537 return namespace;
8486 public boolean isCheckTTL() {
8587 return checkTTL;
8688 }
89
90 public CacheMetadataOptions setUseCacheOnly(boolean useCacheOnly) {
91 this.useCacheOnly = useCacheOnly;
92 return this;
93 }
94
95 public boolean isUseCacheOnly() {
96 return useCacheOnly;
97 }
8798 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 /**
2020 * Utility class providing some cache related facilities.
21 *
21 *
2222 */
2323 public final class CacheUtil {
2424
2525 /**
2626 * Checks that the given pattern is acceptable as a cache pattern
27 *
27 *
2828 * @param cachePattern
2929 * the pattern to check
3030 * @throws IllegalArgumentException
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.UnsupportedEncodingException;
2222 import java.net.MalformedURLException;
2323 import java.net.URL;
24 import java.nio.charset.StandardCharsets;
2425 import java.security.MessageDigest;
2526 import java.security.NoSuchAlgorithmException;
2627 import java.text.ParseException;
28 import java.util.ArrayList;
29 import java.util.Collections;
2730 import java.util.Date;
28 import java.util.Iterator;
31 import java.util.HashMap;
32 import java.util.HashSet;
33 import java.util.List;
2934 import java.util.Map;
35 import java.util.Set;
3036 import java.util.regex.Pattern;
3137
3238 import org.apache.ivy.Ivy;
7177 import org.apache.ivy.util.Message;
7278 import org.apache.ivy.util.PropertiesFile;
7379
80 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
81
7482 public class DefaultRepositoryCacheManager implements RepositoryCacheManager, IvySettingsAware {
7583 private static final String DEFAULT_ARTIFACT_PATTERN = "[organisation]/[module](/[branch])/[type]s/[artifact]-[revision](-[classifier])(.[ext])";
7684
113121
114122 private Boolean useOrigin;
115123
116 private ModuleRules/* <Long> */ttlRules = new ModuleRules();
124 private ModuleRules<Long> ttlRules = new ModuleRules<>();
117125
118126 private Long defaultTTL = null;
119127
120128 private ModuleDescriptorMemoryCache memoryModuleDescrCache;
121129
122130 private PackagingManager packagingManager = new PackagingManager();
131
132 private final List<ConfiguredTTL> configuredTTLs = new ArrayList<>();
123133
124134 public DefaultRepositoryCacheManager() {
125135 }
134144 return settings;
135145 }
136146
137 public void setSettings(IvySettings settings) {
147 public void setSettings(final IvySettings settings) {
138148 this.settings = settings;
139149 packagingManager.setSettings(settings);
150 // process and setup the configured TTLs (which weren't yet processed since they needed
151 // a settings instance to be present)
152 for (final ConfiguredTTL configuredTTL : configuredTTLs) {
153 this.addTTL(configuredTTL.attributes,
154 configuredTTL.matcher == null ? ExactPatternMatcher.INSTANCE : settings.getMatcher(configuredTTL.matcher), configuredTTL.duration);
155 }
156 // clear off the configured TTLs since we have now processed them and created TTL rules
157 // out of them
158 this.configuredTTLs.clear();
140159 }
141160
142161 public File getIvyFileInCache(ModuleRevisionId mrid) {
187206
188207 public long getDefaultTTL() {
189208 if (defaultTTL == null) {
190 defaultTTL = new Long(parseDuration(settings.getVariable("ivy.cache.ttl.default")));
191 }
192 return defaultTTL.longValue();
209 defaultTTL = parseDuration(settings.getVariable("ivy.cache.ttl.default"));
210 }
211 return defaultTTL;
193212 }
194213
195214 public void setDefaultTTL(long defaultTTL) {
196 this.defaultTTL = new Long(defaultTTL);
215 this.defaultTTL = defaultTTL;
197216 }
198217
199218 public void setDefaultTTL(String defaultTTL) {
200 this.defaultTTL = new Long(parseDuration(defaultTTL));
219 this.defaultTTL = parseDuration(defaultTTL);
201220 }
202221
203222 public String getDataFilePattern() {
238257 this.changingPattern = changingPattern;
239258 }
240259
241 public void addTTL(Map attributes, PatternMatcher matcher, long duration) {
242 ttlRules.defineRule(new MapMatcher(attributes, matcher), new Long(duration));
243 }
244
245 public void addConfiguredTtl(Map/* <String,String> */attributes) {
246 String duration = (String) attributes.remove("duration");
247 if (duration == null) {
260 public void addTTL(Map<String, String> attributes, PatternMatcher matcher, long duration) {
261 ttlRules.defineRule(new MapMatcher(attributes, matcher), duration);
262 }
263
264 public void addConfiguredTtl(final Map<String, String> attributes) {
265 final String durationValue = attributes.get("duration");
266 if (durationValue == null) {
248267 throw new IllegalArgumentException("'duration' attribute is mandatory for ttl");
249268 }
250 String matcher = (String) attributes.remove("matcher");
251 addTTL(attributes,
252 matcher == null ? ExactPatternMatcher.INSTANCE : settings.getMatcher(matcher),
253 parseDuration(duration));
269 final long duration = parseDuration(durationValue);
270 final ConfiguredTTL configuredTTL = new ConfiguredTTL(duration, attributes.get("matcher"), attributes);
271 // Processing TTLs requires access to an initialized/usable IvySettings instance.
272 // We keep track of these configured TTLs and process them when the IvySettings instance
273 // becomes usable
274 this.configuredTTLs.add(configuredTTL);
254275 }
255276
256277 public void setMemorySize(int size) {
294315
295316 return days * MILLIS_IN_DAY + hours * MILLIS_IN_HOUR + minutes * MILLIS_IN_MINUTES
296317 + seconds * MILLIS_IN_SECONDS + millis;
297 } else {
298 throw new IllegalArgumentException("invalid duration '" + duration
299 + "': it must match " + DURATION_PATTERN.pattern() + " or 'eternal'");
300 }
318 }
319 throw new IllegalArgumentException("invalid duration '" + duration
320 + "': it must match " + DURATION_PATTERN.pattern() + " or 'eternal'");
301321 }
302322
303323 private int getGroupIntValue(java.util.regex.Matcher m, int groupNumber) {
304324 String g = m.group(groupNumber);
305 return g == null || g.length() == 0 ? 0 : Integer.parseInt(g);
325 return isNullOrEmpty(g) ? 0 : Integer.parseInt(g);
306326 }
307327
308328 /**
309329 * True if this cache should check lastmodified date to know if ivy files are up to date.
310 *
311 * @return
330 *
331 * @return boolean
312332 */
313333 public boolean isCheckmodified() {
314334 if (checkmodified == null) {
315 if (getSettings() != null) {
316 String check = getSettings().getVariable("ivy.resolver.default.check.modified");
317 return check != null ? Boolean.valueOf(check).booleanValue() : false;
318 } else {
319 return false;
320 }
321 } else {
322 return checkmodified.booleanValue();
323 }
335 return getSettings() != null && Boolean
336 .parseBoolean(getSettings().getVariable("ivy.resolver.default.check.modified"));
337 }
338 return checkmodified;
324339 }
325340
326341 public void setCheckmodified(boolean check) {
327 checkmodified = Boolean.valueOf(check);
328 }
329
330 /**
331 * True if this cache should use artifacts original location when possible, false if they should
332 * be copied to cache.
342 checkmodified = check;
343 }
344
345 /**
346 * True if this cache should use artifacts original location when possible, false if they
347 * should be copied to cache.
348 *
349 * @return boolean
333350 */
334351 public boolean isUseOrigin() {
335352 if (useOrigin == null) {
336 if (getSettings() != null) {
337 return getSettings().isDefaultUseOrigin();
338 } else {
339 return false;
340 }
341 } else {
342 return useOrigin.booleanValue();
343 }
353 return getSettings() != null && getSettings().isDefaultUseOrigin();
354 }
355 return useOrigin;
344356 }
345357
346358 public void setUseOrigin(boolean b) {
347 useOrigin = Boolean.valueOf(b);
359 useOrigin = b;
348360 }
349361
350362 /**
351363 * Returns a File object pointing to where the artifact can be found on the local file system.
352364 * This is usually in the cache, but it can be directly in the repository if it is local and if
353365 * the resolve has been done with useOrigin = true
366 *
367 * @param artifact Artifact
368 * @return File
354369 */
355370 public File getArchiveFileInCache(Artifact artifact) {
356371 ArtifactOrigin origin = getSavedArtifactOrigin(artifact);
361376 * Returns a File object pointing to where the artifact can be found on the local file system.
362377 * This is usually in the cache, but it can be directly in the repository if it is local and if
363378 * the resolve has been done with useOrigin = true
379 *
380 * @param artifact Artifact
381 * @param origin ArtifactOrigin
382 * @return File
364383 */
365384 public File getArchiveFileInCache(Artifact artifact, ArtifactOrigin origin) {
366385 File archive = new File(getRepositoryCacheRoot(), getArchivePathInCache(artifact, origin));
379398 * using or not the original location depending on the availability of origin information
380399 * provided as parameter and the setting of useOrigin. If useOrigin is false, this method will
381400 * always return the file in the cache.
401 *
402 * @param artifact Artifact
403 * @param origin ArtifactOrigin
404 * @param useOrigin boolean
405 * @return File
382406 */
383407 private File getArchiveFileInCache(Artifact artifact, ArtifactOrigin origin, boolean useOrigin) {
384408 if (useOrigin && !ArtifactOrigin.isUnknown(origin) && origin.isLocal()) {
385409 return Checks.checkAbsolute(origin.getLocation(), artifact + " origin location");
386 } else {
387 return new File(getRepositoryCacheRoot(), getArchivePathInCache(artifact, origin));
388 }
410 }
411 return new File(getRepositoryCacheRoot(), getArchivePathInCache(artifact, origin));
389412 }
390413
391414 public String getArchivePathInCache(Artifact artifact) {
395418 public String getArchivePathInCache(Artifact artifact, ArtifactOrigin origin) {
396419 if (isOriginalMetadataArtifact(artifact)) {
397420 return IvyPatternHelper.substitute(getIvyPattern() + ".original", artifact, origin);
398 } else {
399 return IvyPatternHelper.substitute(getArtifactPattern(), artifact, origin);
400 }
421 }
422 return IvyPatternHelper.substitute(getArtifactPattern(), artifact, origin);
401423 }
402424
403425 /**
404426 * Saves the information of which resolver was used to resolve a md, so that this info can be
405427 * retrieve later (even after a jvm restart) by getSavedResolverName(ModuleDescriptor md)
406 *
428 *
407429 * @param md
408430 * the module descriptor resolved
409431 * @param name
419441 /**
420442 * Saves the information of which resolver was used to resolve a md, so that this info can be
421443 * retrieve later (even after a jvm restart) by getSavedArtResolverName(ModuleDescriptor md)
422 *
444 *
423445 * @param md
424446 * the module descriptor resolved
425 * @param name
447 * @param metadataResolverName
448 * metadata resolver name
449 * @param artifactResolverName
426450 * artifact resolver name
427451 */
428452 public void saveResolvers(ModuleDescriptor md, String metadataResolverName,
484508 ModuleRevisionId mrid = artifact.getModuleRevisionId();
485509 if (!lockMetadataArtifact(mrid)) {
486510 Message.error("impossible to acquire lock for " + mrid);
487 return ArtifactOrigin.unkwnown(artifact);
511 return ArtifactOrigin.unknown(artifact);
488512 }
489513 try {
490514 PropertiesFile cdf = getCachedDataFile(artifact.getModuleRevisionId());
494518 String exists = cdf.getProperty(getExistsKey(artifact));
495519 String original = cdf.getProperty(getOriginalKey(artifact));
496520
497 boolean isLocal = Boolean.valueOf(local).booleanValue();
521 boolean isLocal = Boolean.valueOf(local);
498522
499523 if (location == null) {
500524 // origin has not been specified, return null
501 return ArtifactOrigin.unkwnown(artifact);
525 return ArtifactOrigin.unknown(artifact);
502526 }
503527
504528 if (original != null) {
530554 // try to find other cached artifact info with same location. This must be the
531555 // origin. We must parse the key as we do not know for sure what the original
532556 // artifact is named.
533 Iterator it = cdf.entrySet().iterator();
534557 String ownLocationKey = getLocationKey(artifact);
535 while (it.hasNext()) {
536 Map.Entry entry = (Map.Entry) it.next();
558 for (Map.Entry<Object, Object> entry : cdf.entrySet()) {
537559 if (entry.getValue().equals(location)
538560 && !ownLocationKey.equals(entry.getKey())) {
539561 // found a match, key is
575597 origin.setLastChecked(Long.valueOf(lastChecked));
576598 }
577599 if (exists != null) {
578 origin.setExist(Boolean.valueOf(exists).booleanValue());
600 origin.setExist(Boolean.valueOf(exists));
579601 }
580602
581603 return origin;
586608
587609 /**
588610 * Creates the unique prefix key that will reference the artifact within the properties.
589 *
611 *
590612 * @param artifact
591613 * the artifact to create the unique key from. Cannot be null.
592614 * @return the unique prefix key as a string.
593615 */
594616 private String getPrefixKey(Artifact artifact) {
617 // use just some visual cue;
595618 // use the hashcode as a uuid for the artifact (fingers crossed)
596 int hashCode = artifact.getId().hashCode();
597 // use just some visual cue
598 return "artifact:" + artifact.getName() + "#" + artifact.getType() + "#"
599 + artifact.getExt() + "#" + hashCode;
619 return String.format("artifact:%s#%s#%s#%d", artifact.getName(), artifact.getType(),
620 artifact.getExt(), artifact.getId().hashCode());
600621 }
601622
602623 /**
603624 * Returns the key used to identify the location of the artifact.
604 *
625 *
605626 * @param artifact
606627 * the artifact to generate the key from. Cannot be null.
607628 * @return the key to be used to reference the artifact location.
608629 */
609630 private String getLocationKey(Artifact artifact) {
610 String prefix = getPrefixKey(artifact);
611 return prefix + ".location";
631 return getPrefixKey(artifact) + ".location";
612632 }
613633
614634 /**
615635 * Returns the key used to identify if the artifact is local.
616 *
636 *
617637 * @param artifact
618638 * the artifact to generate the key from. Cannot be null.
619639 * @return the key to be used to reference the artifact locality.
620640 */
621641 private String getIsLocalKey(Artifact artifact) {
622 String prefix = getPrefixKey(artifact);
623 return prefix + ".is-local";
642 return getPrefixKey(artifact) + ".is-local";
624643 }
625644
626645 /**
627646 * Returns the key used to identify the last time the artifact was checked to be up to date.
628 *
647 *
629648 * @param artifact
630649 * the artifact to generate the key from. Cannot be null.
631650 * @return the key to be used to reference the artifact's last check date.
632651 */
633652 private String getLastCheckedKey(Artifact artifact) {
634 String prefix = getPrefixKey(artifact);
635 return prefix + ".lastchecked";
653 return getPrefixKey(artifact) + ".lastchecked";
636654 }
637655
638656 /**
639657 * Returns the key used to identify the existence of the remote artifact.
640 *
658 *
641659 * @param artifact
642660 * the artifact to generate the key from. Cannot be null.
643661 * @return the key to be used to reference the existence of the artifact.
644662 */
645663 private String getExistsKey(Artifact artifact) {
646 String prefix = getPrefixKey(artifact);
647 return prefix + ".exists";
664 return getPrefixKey(artifact) + ".exists";
648665 }
649666
650667 /**
651668 * Returns the key used to identify the original artifact.
652 *
669 *
653670 * @param artifact
654671 * the artifact to generate the key from. Cannot be null.
655672 * @return the key to be used to reference the original artifact.
656673 */
657674 private String getOriginalKey(Artifact artifact) {
658 String prefix = getPrefixKey(artifact);
659 return prefix + ".original";
675 return getPrefixKey(artifact) + ".original";
660676 }
661677
662678 private PropertiesFile getCachedDataFile(ModuleDescriptor md) {
668684 getDataFilePattern(), mRevId)), "ivy cached data file for " + mRevId);
669685 }
670686
687 /**
688 * A resolver-specific ivydata file, only used for caching dynamic revisions, e.g.
689 * integration-repo.
690 */
691 private PropertiesFile getCachedDataFile(String resolverName, ModuleRevisionId mRevId) {
692 // we append ".${resolverName} onto the end of the regular ivydata location
693 return new PropertiesFile(new File(getRepositoryCacheRoot(),
694 IvyPatternHelper.substitute(getDataFilePattern(), mRevId) + "." + resolverName),
695 "ivy cached data file for " + mRevId);
696 }
697
671698 public ResolvedModuleRevision findModuleInCache(DependencyDescriptor dd,
672699 ModuleRevisionId requestedRevisionId, CacheMetadataOptions options,
673700 String expectedResolver) {
674 ModuleRevisionId mrid = requestedRevisionId;
675701 if (isCheckmodified(dd, requestedRevisionId, options)) {
676 Message.verbose("don't use cache for " + mrid + ": checkModified=true");
702 Message.verbose("don't use cache for " + requestedRevisionId + ": checkModified=true");
677703 return null;
678704 }
679 if (isChanging(dd, requestedRevisionId, options)) {
680 Message.verbose("don't use cache for " + mrid + ": changing=true");
705 if (!options.isUseCacheOnly() && isChanging(dd, requestedRevisionId, options)) {
706 Message.verbose("don't use cache for " + requestedRevisionId + ": changing=true");
681707 return null;
682708 }
683 return doFindModuleInCache(mrid, options, expectedResolver);
709 return doFindModuleInCache(requestedRevisionId, options, expectedResolver);
684710 }
685711
686712 private ResolvedModuleRevision doFindModuleInCache(ModuleRevisionId mrid,
694720
695721 try {
696722 if (settings.getVersionMatcher().isDynamic(mrid)) {
697 String resolvedRevision = getResolvedRevision(mrid, options);
698 if (resolvedRevision != null) {
699 Message.verbose("found resolved revision in cache: " + mrid + " => "
700 + resolvedRevision);
701
702 // we have found another module in the cache, make sure we unlock
703 // the original module
704 unlockMetadataArtifact(mrid);
705 mrid = ModuleRevisionId.newInstance(mrid, resolvedRevision);
706
707 // don't forget to request a lock on the new module!
708 if (!lockMetadataArtifact(mrid)) {
709 Message.error("impossible to acquire lock for " + mrid);
710
711 // we couldn't lock the new module, so no need to unlock it
712 unlock = false;
713 return null;
714 }
715 } else {
723 String resolvedRevision = getResolvedRevision(expectedResolver, mrid, options);
724 if (resolvedRevision == null) {
725 return null;
726 }
727 Message.verbose("found resolved revision in cache: " + mrid + " => "
728 + resolvedRevision);
729
730 // we have found another module in the cache, make sure we unlock
731 // the original module
732 unlockMetadataArtifact(mrid);
733 mrid = ModuleRevisionId.newInstance(mrid, resolvedRevision);
734
735 // don't forget to request a lock on the new module!
736 if (!lockMetadataArtifact(mrid)) {
737 Message.error("impossible to acquire lock for " + mrid);
738
739 // we couldn't lock the new module, so no need to unlock it
740 unlock = false;
716741 return null;
717742 }
718743 }
765790 }
766791 }
767792 return new ResolvedModuleRevision(resolver, artResolver, depMD, madr);
768 } else {
769 Message.debug("found module in cache but with a different resolver: "
770 + "discarding: " + mrid + "; expected resolver="
771 + expectedResolver + "; resolver=" + resolver.getName());
772793 }
794 Message.debug("found module in cache but with a different resolver: "
795 + "discarding: " + mrid + "; expected resolver="
796 + expectedResolver + "; resolver=" + resolver.getName());
773797 } else {
774798 Message.debug("\tresolver not found: " + resolverName
775799 + " => cannot use cached ivy file for " + mrid);
791815
792816 /**
793817 * Choose write module descriptor parser for a given moduleDescriptor
794 *
818 *
795819 * @param moduleDescriptorFile
796820 * a given module descriptor
797 * @return
821 * @return ModuleDescriptorParser
798822 */
799823 protected ModuleDescriptorParser getModuleDescriptorParser(File moduleDescriptorFile) {
800824 return XmlModuleDescriptorParser.getInstance();
833857 return cache.getStale(ivyFile, settings, options.isValidate(), mdProvider);
834858 }
835859
836 private String getResolvedRevision(ModuleRevisionId mrid, CacheMetadataOptions options) {
860 /**
861 * Called by doFindModuleInCache to lookup the dynamic {@code mrid} in the ivycache's ivydata
862 * file.
863 */
864 private String getResolvedRevision(String expectedResolver, ModuleRevisionId mrid, CacheMetadataOptions options) {
837865 if (!lockMetadataArtifact(mrid)) {
838866 Message.error("impossible to acquire lock for " + mrid);
839867 return null;
840868 }
841869 try {
842 String resolvedRevision = null;
843870 if (options.isForce()) {
844871 Message.verbose("refresh mode: no check for cached resolved revision for " + mrid);
845872 return null;
846873 }
847 PropertiesFile cachedResolvedRevision = getCachedDataFile(mrid);
848 resolvedRevision = cachedResolvedRevision.getProperty("resolved.revision");
874 // If a resolver is asking for its specific dynamic revision, avoid looking at a different one
875 PropertiesFile cachedResolvedRevision;
876 if (expectedResolver != null) {
877 cachedResolvedRevision = getCachedDataFile(expectedResolver, mrid);
878 } else {
879 cachedResolvedRevision = getCachedDataFile(mrid);
880 }
881 String resolvedRevision = cachedResolvedRevision.getProperty("resolved.revision");
849882 if (resolvedRevision == null) {
850883 Message.verbose(getName() + ": no cached resolved revision for " + mrid);
851884 return null;
855888 if (resolvedTime == null) {
856889 Message.verbose(getName()
857890 + ": inconsistent or old cache: no cached resolved time for " + mrid);
858 saveResolvedRevision(mrid, resolvedRevision);
891 saveResolvedRevision(expectedResolver, mrid, resolvedRevision);
859892 return resolvedRevision;
860893 }
861894 if (options.isCheckTTL()) {
862895 long expiration = Long.parseLong(resolvedTime) + getTTL(mrid);
863 if (expiration > 0 // negative expiration means that Long.MAX_VALUE has been
864 // exceeded
865 && System.currentTimeMillis() > expiration) {
896 // negative expiration means that Long.MAX_VALUE has been exceeded
897 if (expiration > 0 && System.currentTimeMillis() > expiration) {
866898 Message.verbose(getName() + ": cached resolved revision expired for " + mrid);
867899 return null;
868900 }
873905 }
874906 }
875907
908 @Deprecated
876909 public void saveResolvedRevision(ModuleRevisionId mrid, String revision) {
910 saveResolvedRevision(null, mrid, revision);
911 }
912
913 public void saveResolvedRevision(String resolverName, ModuleRevisionId mrid, String revision) {
877914 if (!lockMetadataArtifact(mrid)) {
878915 Message.error("impossible to acquire lock for " + mrid);
879916 return;
880917 }
881918 try {
882 PropertiesFile cachedResolvedRevision = getCachedDataFile(mrid);
919 PropertiesFile cachedResolvedRevision;
920 if (resolverName == null) {
921 cachedResolvedRevision = getCachedDataFile(mrid);
922 } else {
923 cachedResolvedRevision = getCachedDataFile(resolverName, mrid);
924 }
883925 cachedResolvedRevision.setProperty("resolved.time",
884926 String.valueOf(System.currentTimeMillis()));
885927 cachedResolvedRevision.setProperty("resolved.revision", revision);
928 if (resolverName != null) {
929 cachedResolvedRevision.setProperty("resolver", resolverName);
930 }
886931 cachedResolvedRevision.save();
887932 } finally {
888933 unlockMetadataArtifact(mrid);
890935 }
891936
892937 public long getTTL(ModuleRevisionId mrid) {
893 Long ttl = (Long) ttlRules.getRule(mrid);
894 return ttl == null ? getDefaultTTL() : ttl.longValue();
895 }
896
938 Long ttl = ttlRules.getRule(mrid);
939 return ttl == null ? getDefaultTTL() : ttl;
940 }
941
942 @Override
897943 public String toString() {
898944 return name;
899945 }
10271073 File archiveFile = getArchiveFileInCache(unpacked, null, false);
10281074 if (archiveFile.exists() && !options.isForce()) {
10291075 adr.setUnpackedLocalFile(archiveFile);
1076 adr.setUnpackedArtifact(unpacked);
10301077 } else {
10311078 Message.info("\tUnpacking " + artifact.getId());
10321079 try {
1033 packagingManager.unpackArtifact(artifact, adr.getLocalFile(), archiveFile);
1080 final Artifact unpackedArtifact = packagingManager.unpackArtifact(artifact, adr.getLocalFile(), archiveFile);
10341081 adr.setUnpackedLocalFile(archiveFile);
1082 adr.setUnpackedArtifact(unpackedArtifact);
10351083 } catch (Exception e) {
10361084 Message.debug(e);
10371085 adr.setDownloadStatus(DownloadStatus.FAILED);
10791127 }
10801128 } else {
10811129 long start = System.currentTimeMillis();
1082 origin.setLastChecked(new Long(start));
1130 origin.setLastChecked(start);
10831131 try {
10841132 ResolvedResource artifactRef = new ResolvedResource(resource,
10851133 Ivy.getWorkingRevision());
11341182
11351183 /**
11361184 * Compute a SHA1 of the resource name, encoded in base64, so we can use it as a file name.
1137 *
1185 *
11381186 * @param resource
11391187 * the resource which name will be hashed
11401188 * @return the hash
11411189 */
11421190 private String computeResourceNameHash(Resource resource) {
1143 byte[] shaDigest;
1144 try {
1145 shaDigest = SHA_DIGEST.digest(resource.getName().getBytes("UTF-8"));
1146 } catch (UnsupportedEncodingException e) {
1147 throw new RuntimeException("UTF-8 not supported", e);
1148 }
1149 return HexEncoder.encode(shaDigest);
1191 return HexEncoder.encode(SHA_DIGEST.digest(resource.getName().getBytes(StandardCharsets.UTF_8)));
11501192 }
11511193
11521194 /**
11531195 * Check that a cached file can be considered up to date and thus not downloaded
1154 *
1196 *
11551197 * @param archiveFile
11561198 * the file in the cache
11571199 * @param resource
11681210 ArtifactOrigin savedOrigin, ArtifactOrigin origin, long ttl) {
11691211 long time = System.currentTimeMillis();
11701212 if (savedOrigin.getLastChecked() != null
1171 && (time - savedOrigin.getLastChecked().longValue()) < ttl) {
1213 && (time - savedOrigin.getLastChecked()) < ttl) {
11721214 // still in the ttl period, no need to check, trust the cache
1173 if (!archiveFile.exists()) {
1174 // but if the local archive doesn't exist, trust the cache only if the cached origin
1175 // says that the remote resource doesn't exist either
1176 return !savedOrigin.isExists();
1177 }
1178 return true;
1215 return archiveFile.exists() || !savedOrigin.isExists();
11791216 }
11801217 if (!archiveFile.exists()) {
11811218 // the the file doesn't exist in the cache, obviously not up to date
11821219 return false;
11831220 }
1184 origin.setLastChecked(new Long(time));
1221 origin.setLastChecked(time);
11851222 // check if the local resource is up to date regarding the remote one
11861223 return archiveFile.lastModified() >= resource.getLastModified();
11871224 }
11881225
11891226 public void originalToCachedModuleDescriptor(DependencyResolver resolver,
1190 ResolvedResource orginalMetadataRef, Artifact requestedMetadataArtifact,
1191 ResolvedModuleRevision rmr, ModuleDescriptorWriter writer) {
1227 ResolvedResource originalMetadataRef, Artifact requestedMetadataArtifact,
1228 ResolvedModuleRevision rmr, ModuleDescriptorWriter writer) {
11921229 ModuleDescriptor md = rmr.getDescriptor();
11931230 Artifact originalMetadataArtifact = getOriginalMetadataArtifact(requestedMetadataArtifact);
11941231 File mdFileInCache = getIvyFileInCache(md.getResolvedModuleRevisionId());
12001237 }
12011238 try {
12021239 File originalFileInCache = getArchiveFileInCache(originalMetadataArtifact);
1203 writer.write(orginalMetadataRef, md, originalFileInCache, mdFileInCache);
1240 writer.write(originalMetadataRef, md, originalFileInCache, mdFileInCache);
12041241
12051242 getMemoryCache().putInCache(mdFileInCache, new ParserSettingsMonitor(settings), true,
12061243 md);
12141251 throw e;
12151252 } catch (Exception e) {
12161253 String metadataRef;
1217 if (orginalMetadataRef == null) {
1254 if (originalMetadataRef == null) {
12181255 metadataRef = String.valueOf(md.getResolvedModuleRevisionId());
12191256 } else {
1220 metadataRef = String.valueOf(orginalMetadataRef);
1257 metadataRef = String.valueOf(originalMetadataRef);
12211258 }
12221259 Message.warn("impossible to put metadata file in cache: " + metadataRef, e);
12231260 } finally {
12841321 + mrid);
12851322 rmr.getReport().setSearched(true);
12861323 return rmr;
1287 } else {
1288 Message.verbose("\t" + getName()
1289 + ": revision in cache is not up to date: " + mrid);
1290 if (isChanging(dd, mrid, options)) {
1291 // ivy file has been updated, we should see if it has a new publication
1292 // date to see if a new download is required (in case the dependency is
1293 // a changing one)
1294 cachedPublicationDate = rmr.getDescriptor()
1295 .getResolvedPublicationDate();
1296 }
1324 }
1325 Message.verbose("\t" + getName()
1326 + ": revision in cache is not up to date: " + mrid);
1327 if (isChanging(dd, mrid, options)) {
1328 // ivy file has been updated, we should see if it has a new publication
1329 // date to see if a new download is required (in case the dependency is
1330 // a changing one)
1331 cachedPublicationDate = rmr.getDescriptor()
1332 .getResolvedPublicationDate();
12971333 }
12981334 }
12991335 }
13261362 parserSettings);
13271363 if (md == null) {
13281364 throw new IllegalStateException(
1329 "module descriptor parser returned a null module descriptor, "
1330 + "which is not allowed. " + "parser=" + parser
1331 + "; parser class=" + parser.getClass().getName()
1365 "module descriptor parser returned a null module descriptor, which is not allowed. parser="
1366 + parser + "; parser class=" + parser.getClass().getName()
13321367 + "; module descriptor resource=" + mdRef.getResource());
13331368 }
13341369 Message.debug("\t" + getName() + ": parsed downloaded md file for " + mrid
13431378 deleteOldArtifacts = true;
13441379 }
13451380 if (deleteOldArtifacts) {
1346 String[] confs = md.getConfigurationsNames();
1347 for (int i = 0; i < confs.length; i++) {
1348 Artifact[] arts = md.getArtifacts(confs[i]);
1349 for (int j = 0; j < arts.length; j++) {
1350 Artifact transformedArtifact = NameSpaceHelper.transform(arts[j],
1381 for (String conf : md.getConfigurationsNames()) {
1382 for (Artifact art : md.getArtifacts(conf)) {
1383 Artifact transformedArtifact = NameSpaceHelper.transform(art,
13511384 options.getNamespace().getToSystemTransformer());
13521385 ArtifactOrigin origin = getSavedArtifactOrigin(transformedArtifact);
13531386 File artFile = getArchiveFileInCache(transformedArtifact, origin, false);
14011434 private boolean lockMetadataArtifact(ModuleRevisionId mrid) {
14021435 Artifact artifact = getDefaultMetadataArtifact(mrid);
14031436 try {
1404 // we need to provide an artifact origin to be sure we do not end up in a stack overflow
1405 // if the cache pattern is using original name, and the substitution thus trying to get
1406 // the saved artifact origin value which in turns calls this method
1437 // we need to provide an artifact origin to be sure we do not end up in a stack
1438 // overflow if the cache pattern is using original name, and the substitution thus
1439 // trying to get the saved artifact origin value which in turns calls this method
14071440 return getLockStrategy().lockArtifact(artifact,
14081441 getArchiveFileInCache(artifact, getDefaultMetadataArtifactOrigin(mrid)));
14091442 } catch (InterruptedException e) {
14191452 }
14201453
14211454 private ArtifactOrigin getDefaultMetadataArtifactOrigin(ModuleRevisionId mrid) {
1455 final String location;
1456 try {
1457 location = this.getIvyFileInCache(mrid).toURI().toURL().toExternalForm();
1458 } catch (MalformedURLException e) {
1459 throw new RuntimeException("Failed to determine artifact origin for " + mrid);
1460 }
14221461 // it's important to say the origin is not local to make sure it won't ever be used for
14231462 // anything else than original token
1424 return new ArtifactOrigin(DefaultArtifact.newIvyArtifact(mrid, null), false,
1425 getIvyFileInCache(mrid).getPath());
1463 return new ArtifactOrigin(DefaultArtifact.newIvyArtifact(mrid, null), false, location);
14261464 }
14271465
14281466 private Artifact getDefaultMetadataArtifact(ModuleRevisionId mrid) {
14291467 return new DefaultArtifact(mrid, new Date(), "metadata", "metadata", "ivy", true);
14301468 }
14311469
1432 // not used any more, but maybe useful for finer grain locking when downloading artifacts
1470 // not used any more, but may be useful for finer grained locking when downloading artifacts
14331471 // private boolean lockArtifact(Artifact artifact) {
14341472 // try {
14351473 // return getLockStrategy().lockArtifact(artifact,
14771515
14781516 private boolean isCheckmodified(DependencyDescriptor dd, ModuleRevisionId requestedRevisionId,
14791517 CacheMetadataOptions options) {
1480 if (options.isCheckmodified() != null) {
1481 return options.isCheckmodified().booleanValue();
1482 }
1483 return isCheckmodified();
1518 return options.isCheckmodified() == null ? isCheckmodified() : options.isCheckmodified();
14841519 }
14851520
14861521 public void clean() {
14991534 /**
15001535 * Resource downloader which makes a copy of the previously existing file before overriding it.
15011536 * <p>
1502 * The backup file can be restored or cleanuped later
1537 * The backup file can be restored or cleaned up later
15031538 */
15041539 private final class BackupResourceDownloader implements ResourceDownloader {
15051540
15241559 }
15251560
15261561 public void restore() throws IOException {
1527 if ((backup != null) && backup.exists()) {
1562 if (backup != null && backup.exists()) {
15281563 File original = new File(originalPath);
15291564 FileUtil.copy(backup, original, null, true);
15301565 backup.delete();
15321567 }
15331568
15341569 public void cleanUp() {
1535 if ((backup != null) && backup.exists()) {
1570 if (backup != null && backup.exists()) {
15361571 backup.delete();
15371572 }
15381573 }
15391574
15401575 }
15411576
1577 private static final class ConfiguredTTL {
1578 // attributes on the TTL, that don't contribute to module matching
1579 private static final Set<String> attributesNotContributingToMatching = new HashSet<>();
1580 static {
1581 attributesNotContributingToMatching.add("duration");
1582 attributesNotContributingToMatching.add("matcher");
1583 }
1584
1585 private final String matcher;
1586 private final long duration;
1587 private final Map<String, String> attributes;
1588
1589 private ConfiguredTTL(final long duration, final String matcher, final Map<String, String> attributes) {
1590 this.matcher = matcher;
1591 this.duration = duration;
1592 if (attributes == null) {
1593 this.attributes = Collections.emptyMap();
1594 } else {
1595 final Map<String, String> attrs = new HashMap<>(attributes);
1596 for (final String removable : attributesNotContributingToMatching) {
1597 attrs.remove(removable);
1598 }
1599 this.attributes = Collections.unmodifiableMap(attrs);
1600 }
1601 }
1602
1603 }
15421604 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535 import org.apache.ivy.core.module.id.ModuleRevisionId;
3636 import org.apache.ivy.core.module.status.StatusManager;
3737 import org.apache.ivy.core.settings.IvySettings;
38 import org.apache.ivy.core.settings.TimeoutConstraint;
3839 import org.apache.ivy.plugins.IvySettingsAware;
3940 import org.apache.ivy.plugins.conflict.ConflictManager;
4041 import org.apache.ivy.plugins.matcher.PatternMatcher;
7374 }
7475
7576 public File getResolutionCacheRoot() {
77 if (basedir == null) {
78 if (settings == null) {
79 throw new IllegalStateException("The 'basedir' or 'IvySettings' has not been set on the ResolutionCacheManager");
80 }
81 basedir = settings.getDefaultResolutionCacheBasedir();
82 }
7683 return basedir;
7784 }
7885
129136 final String suffix = ".xml";
130137 return getResolutionCacheRoot().listFiles(new FilenameFilter() {
131138 public boolean accept(File dir, String name) {
132 return (name.startsWith(prefix) && name.endsWith(suffix));
139 return name.startsWith(prefix) && name.endsWith(suffix);
133140 }
134141 });
135142 }
159166
160167 /**
161168 * Choose write module descriptor parser for a given moduleDescriptor
162 *
169 *
163170 * @param moduleDescriptorFile
164171 * a given module descriptor
165 * @return
172 * @return ModuleDescriptorParser
166173 */
167174 protected ModuleDescriptorParser getModuleDescriptorParser(File moduleDescriptorFile) {
168175 return XmlModuleDescriptorParser.getInstance();
188195
189196 private void saveLocalParents(ModuleRevisionId baseMrevId, ModuleDescriptor md, File mdFile,
190197 Properties paths) throws ParseException, IOException {
191 ExtendsDescriptor[] parents = md.getInheritedDescriptors();
192 for (int i = 0; i < parents.length; i++) {
193 if (!parents[i].isLocal()) {
198 for (ExtendsDescriptor parent : md.getInheritedDescriptors()) {
199 if (!parent.isLocal()) {
194200 // we store only local parents in the cache!
195201 continue;
196202 }
197203
198 ModuleDescriptor parent = parents[i].getParentMd();
204 ModuleDescriptor parentMd = parent.getParentMd();
199205 ModuleRevisionId pRevId = ModuleRevisionId.newInstance(baseMrevId,
200206 baseMrevId.getRevision() + "-parent." + paths.size());
201207 File parentFile = getResolvedIvyFileInCache(pRevId);
202 parent.toIvyFile(parentFile);
203
204 paths.setProperty(mdFile.getName() + "|" + parents[i].getLocation(),
208 parentMd.toIvyFile(parentFile);
209
210 paths.setProperty(mdFile.getName() + "|" + parent.getLocation(),
205211 parentFile.getAbsolutePath());
206 saveLocalParents(baseMrevId, parent, parentFile, paths);
212 saveLocalParents(baseMrevId, parentMd, parentFile, paths);
207213 }
208214 }
209215
212218 }
213219
214220 public void clean() {
215 FileUtil.forceDelete(getBasedir());
221 FileUtil.forceDelete(getResolutionCacheRoot());
216222 }
217223
218224 private static class CacheParserSettings implements ParserSettings {
219225
220226 private ParserSettings delegate;
221227
222 private Map parentPaths;
223
224 public CacheParserSettings(ParserSettings delegate, Map parentPaths) {
228 private Map<Object, Object> parentPaths;
229
230 public CacheParserSettings(ParserSettings delegate, Map<Object, Object> parentPaths) {
225231 this.delegate = delegate;
226232 this.parentPaths = parentPaths;
227233 }
230236 return delegate.substitute(value);
231237 }
232238
233 public Map substitute(Map strings) {
239 public Map<String, String> substitute(Map<String, String> strings) {
234240 return delegate.substitute(strings);
235241 }
236242
273279 public Namespace getContextNamespace() {
274280 return delegate.getContextNamespace();
275281 }
276 }
277
278 private static class MapURLResolver extends RelativeUrlResolver {
279
280 private Map paths;
282
283 public String getVariable(String value) {
284 return delegate.getVariable(value);
285 }
286
287 @Override
288 public TimeoutConstraint getTimeoutConstraint(final String name) {
289 return this.delegate.getTimeoutConstraint(name);
290 }
291 }
292
293 private static final class MapURLResolver extends RelativeUrlResolver {
294
295 private Map<Object, Object> paths;
281296
282297 private RelativeUrlResolver delegate;
283298
284 private MapURLResolver(Map paths, RelativeUrlResolver delegate) {
299 private MapURLResolver(Map<Object, Object> paths, RelativeUrlResolver delegate) {
285300 this.paths = paths;
286301 this.delegate = delegate;
287302 }
288303
289304 public URL getURL(URL context, String url) throws MalformedURLException {
290305 String path = context.getPath();
291 if (path.indexOf('/') >= 0) {
306 if (path.contains("/")) {
292307 String file = path.substring(path.lastIndexOf('/') + 1);
293308
294309 if (paths.containsKey(file + "|" + url)) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
2424
2525 public interface DownloadListener {
26 public void needArtifact(RepositoryCacheManager cache, Artifact artifact);
26 void needArtifact(RepositoryCacheManager cache, Artifact artifact);
2727
28 public void startArtifactDownload(RepositoryCacheManager cache, ResolvedResource rres,
28 void startArtifactDownload(RepositoryCacheManager cache, ResolvedResource rres,
2929 Artifact artifact, ArtifactOrigin origin);
3030
31 public void endArtifactDownload(RepositoryCacheManager cache, Artifact artifact,
31 void endArtifactDownload(RepositoryCacheManager cache, Artifact artifact,
3232 ArtifactDownloadReport adr, File archiveFile);
3333 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.core.cache;
1818
19 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
20 import org.apache.ivy.plugins.parser.ParserSettings;
21 import org.apache.ivy.util.Message;
22
1923 import java.io.File;
2024 import java.io.IOException;
2125 import java.text.ParseException;
2226 import java.util.Iterator;
2327 import java.util.LinkedHashMap;
24
25 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
26 import org.apache.ivy.plugins.parser.ParserSettings;
27 import org.apache.ivy.util.Message;
2828
2929 /**
3030 * Cache ModuleDescriptors so that when the same module is used twice (in multi-module build for
3636
3737 private final int maxSize;
3838
39 private final LinkedHashMap/* <File,CacheEntry> */valueMap;
39 private final LinkedHashMap<File, CacheEntry> valueMap;
4040
4141 /**
4242 * Create a cache of the given size
43 *
44 * @param size
43 *
44 * @param size int
4545 */
4646 public ModuleDescriptorMemoryCache(int size) {
4747 this.maxSize = size;
48 this.valueMap = new LinkedHashMap(size);
48 this.valueMap = new LinkedHashMap<>(size);
4949 }
5050
5151 public ModuleDescriptor get(File ivyFile, ParserSettings ivySettings, boolean validated,
7272
7373 ModuleDescriptor getFromCache(File ivyFile, ParserSettings ivySettings, boolean validated) {
7474 if (maxSize <= 0) {
75 // cache is disbaled
75 // cache is disabled
7676 return null;
7777 }
78 CacheEntry entry = (CacheEntry) valueMap.get(ivyFile);
79 if (entry != null) {
80 if (entry.isStale(validated, ivySettings)) {
81 Message.debug("Entry is found in the ModuleDescriptorCache but entry should be "
82 + "reevaluated : " + ivyFile);
83 valueMap.remove(ivyFile);
78 synchronized (valueMap) {
79 CacheEntry entry = valueMap.get(ivyFile);
80 if (entry != null) {
81 if (entry.isStale(ivyFile, validated, ivySettings)) {
82 Message.debug("Entry is found in the ModuleDescriptorCache but entry should be "
83 + "reevaluated : " + ivyFile);
84 valueMap.remove(ivyFile);
85 return null;
86 } else {
87 // Move the entry at the end of the list
88 valueMap.remove(ivyFile);
89 valueMap.put(ivyFile, entry);
90 Message.debug("Entry is found in the ModuleDescriptorCache : " + ivyFile);
91 return entry.md;
92 }
93 } else {
94 Message.debug("No entry is found in the ModuleDescriptorCache : " + ivyFile);
8495 return null;
85 } else {
86 // Move the entry at the end of the list
87 valueMap.remove(ivyFile);
88 valueMap.put(ivyFile, entry);
89 Message.debug("Entry is found in the ModuleDescriptorCache : " + ivyFile);
90 return entry.md;
9196 }
92 } else {
93 Message.debug("No entry is found in the ModuleDescriptorCache : " + ivyFile);
94 return null;
9597 }
9698 }
9799
101103 // cache is disabled
102104 return;
103105 }
104 if (valueMap.size() >= maxSize) {
105 Message.debug("ModuleDescriptorCache is full, remove one entry");
106 Iterator it = valueMap.values().iterator();
107 it.next();
108 it.remove();
106 synchronized (valueMap) {
107 if (valueMap.size() >= maxSize) {
108 Message.debug("ModuleDescriptorCache is full, remove one entry");
109 Iterator<CacheEntry> it = valueMap.values().iterator();
110 it.next();
111 it.remove();
112 }
113 valueMap.put(url, new CacheEntry(descriptor, validated, ivySettingsMonitor));
109114 }
110 valueMap.put(url, new CacheEntry(descriptor, validated, ivySettingsMonitor));
111115 }
112116
113117 private static class CacheEntry {
124128 this.parserSettingsMonitor = parserSettingsMonitor;
125129 }
126130
127 boolean isStale(boolean validated, ParserSettings newParserSettings) {
131 boolean isStale(File ivyFile, boolean validated, ParserSettings newParserSettings) {
128132 return (validated && !this.validated)
133 || md.getLastModified() != ivyFile.lastModified()
129134 || parserSettingsMonitor.hasChanged(newParserSettings);
130135 }
131136 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525
2626 interface ModuleDescriptorProvider {
2727
28 public ModuleDescriptor provideModule(ParserSettings ivySettings, File descriptorFile,
28 ModuleDescriptor provideModule(ParserSettings ivySettings, File descriptorFile,
2929 boolean validate) throws ParseException, IOException;
3030 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
2525
2626 public interface ModuleDescriptorWriter {
27 public void write(ResolvedResource originalMdResource, ModuleDescriptor md, File src, File dest)
27 void write(ResolvedResource originalMdResource, ModuleDescriptor md, File src, File dest)
2828 throws IOException, ParseException;
2929 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.io.File;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.LinkedHashMap;
2322 import java.util.Map;
24 import java.util.Map.Entry;
2523
2624 import org.apache.ivy.core.RelativeUrlResolver;
2725 import org.apache.ivy.core.module.id.ModuleId;
2826 import org.apache.ivy.core.module.id.ModuleRevisionId;
2927 import org.apache.ivy.core.module.status.StatusManager;
28 import org.apache.ivy.core.settings.TimeoutConstraint;
3029 import org.apache.ivy.plugins.conflict.ConflictManager;
3130 import org.apache.ivy.plugins.matcher.PatternMatcher;
3231 import org.apache.ivy.plugins.namespace.Namespace;
3837 * Keep traces of the usage of a ParserSettings in order to check afterwards that the relevant
3938 * settings didn't changed.
4039 * <p>
41 * A ParserSettingsMonitor provide a ParserSettings that must be used in place of the orignal one.
40 * A ParserSettingsMonitor provide a ParserSettings that must be used in place of the original one.
4241 * </p>
4342 * <p>
4443 * The current implementation consider that a settings changed iff one of the used variable has
4948
5049 private ParserSettings delegatedSettings;
5150
52 private final Map/* <String,String> */substitutes;
51 private final Map<String, String> substitutes;
5352
5453 public ParserSettingsMonitor(ParserSettings settings) {
5554 this.delegatedSettings = settings;
56 this.substitutes = new HashMap();
55 this.substitutes = new HashMap<>();
5756 }
5857
5958 /**
60 * @return The parser settings that must be used in place of the orignal settings The returned
59 * @return The parser settings that must be used in place of the original settings The returned
6160 * object delegates all the call to the original settings.
6261 */
6362 public ParserSettings getMonitoredSettings() {
6564 }
6665
6766 /**
68 * Free the ressource used during the monitoring, keeping only the info required to evaluate
67 * Free the resource used during the monitoring, keeping only the info required to evaluate
6968 * hasChanged.
7069 */
7170 public void endMonitoring() {
7877 * Only the info that was actually used is compared.
7978 */
8079 public boolean hasChanged(ParserSettings newSettings) {
81 for (Iterator it = substitutes.entrySet().iterator(); it.hasNext();) {
82 Map.Entry entry = (Entry) it.next();
83 String key = (String) entry.getKey();
84 Object oldValue = entry.getValue();
85 String newValue = newSettings.substitute(key);
86 if (!oldValue.equals(newValue)) {
87 Message.debug("settings variable has changed for : " + entry.getKey());
80 for (Map.Entry<String, String> entry : substitutes.entrySet()) {
81 String key = entry.getKey();
82 if (!entry.getValue().equals(newSettings.substitute(key))) {
83 Message.debug("settings variable has changed for : " + key);
8884 return true;
8985 }
9086 }
133129 return delegatedSettings.getContextNamespace();
134130 }
135131
136 public Map substitute(Map strings) {
137 Map substituted = new LinkedHashMap();
138 for (Iterator it = strings.entrySet().iterator(); it.hasNext();) {
139 Map.Entry entry = (Map.Entry) it.next();
140 substituted.put(entry.getKey(), substitute((String) entry.getValue()));
132 public Map<String, String> substitute(Map<String, String> strings) {
133 Map<String, String> substituted = new LinkedHashMap<>();
134 for (Map.Entry<String, String> entry : strings.entrySet()) {
135 substituted.put(entry.getKey(), substitute(entry.getValue()));
141136 }
142137 return substituted;
143138 }
144139
145140 public String substitute(String value) {
146141 String r = delegatedSettings.substitute(value);
147 if (value != null && value != r) {
142 if (value != null && !value.equals(r)) {
148143 substitutes.put(value, r);
149144 }
150145 return r;
151146 }
147
148 public String getVariable(String value) {
149 return delegatedSettings.getVariable(value);
150 }
151
152 @Override
153 public TimeoutConstraint getTimeoutConstraint(final String name) {
154 return delegatedSettings.getTimeoutConstraint(name);
155 }
152156 };
153157 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535
3636 /**
3737 * Returns the name of the repository cache manager.
38 *
38 *
3939 * @return the name of the repository cache manager.
4040 */
41 public abstract String getName();
41 String getName();
4242
4343 /**
4444 * Saves the information of which resolvers were used to resolve a module (both for metadata and
4545 * artifact), so that this info can be loaded later (even after a jvm restart) for the use of
46 * {@link #findModuleInCache(DependencyDescriptor, CacheMetadataOptions, String)}.
47 *
48 * @param md
49 * the module descriptor resolved
50 * @param metadataResolverName
51 * metadata resolver name
52 * @param artifactResolverName
53 * artifact resolver name
46 * {@link #findModuleInCache(DependencyDescriptor, ModuleRevisionId, CacheMetadataOptions, String)}.
47 *
48 * @param descriptor the module descriptor resolved
49 * @param metadataResolverName metadata resolver name
50 * @param artifactResolverName artifact resolver name
5451 */
55 public abstract void saveResolvers(ModuleDescriptor descriptor, String metadataResolverName,
56 String artifactResolverName);
52 void saveResolvers(ModuleDescriptor descriptor, String metadataResolverName,
53 String artifactResolverName);
5754
5855 /**
5956 * Returns the artifact origin of the given artifact as saved in this cache.
6057 * <p>
6158 * If the origin is unknown, the returned ArtifactOrigin instance will return true when
6259 * {@link ArtifactOrigin#isUnknown(ArtifactOrigin)} is called.
63 *
64 * @param artifact
65 * the artifact for which the saved artifact origin should be returned.
60 *
61 * @param artifact the artifact for which the saved artifact origin should be returned.
6662 * @return the artifact origin of the given artifact as saved in this cache
6763 */
68 public abstract ArtifactOrigin getSavedArtifactOrigin(Artifact artifact);
64 ArtifactOrigin getSavedArtifactOrigin(Artifact artifact);
6965
7066 /**
7167 * Search a module descriptor in cache for a mrid
72 *
73 * @param dd
74 * the dependency descriptor identifying the module to search
75 * @param requestedRevisionId
76 * the requested dependency module revision id identifying the module to search
77 * @param options
78 * options on how caching should be handled
79 * @param expectedResolver
80 * the resolver with which the md in cache must have been resolved to be returned,
81 * null if this doesn't matter
68 *
69 * @param dd the dependency descriptor identifying the module to search
70 * @param requestedRevisionId the requested dependency module revision id identifying the module
71 * to search
72 * @param options options on how caching should be handled
73 * @param expectedResolver the resolver with which the md in cache must have been resolved to
74 * be returned, null if this doesn't matter
8275 * @return the ResolvedModuleRevision corresponding to the module found, null if none correct
83 * has been found in cache
76 * has been found in cache
8477 */
85 public abstract ResolvedModuleRevision findModuleInCache(DependencyDescriptor dd,
86 ModuleRevisionId requestedRevisionId, CacheMetadataOptions options,
87 String expectedResolver);
78 ResolvedModuleRevision findModuleInCache(DependencyDescriptor dd,
79 ModuleRevisionId requestedRevisionId,
80 CacheMetadataOptions options,
81 String expectedResolver);
8882
8983 /**
9084 * Downloads an artifact to this cache.
91 *
92 * @param artifact
93 * the artifact to download
94 * @param resourceResolver
95 * a resource resolver to use if the artifact needs to be resolved to a Resource for
96 * downloading
97 * @param resourceDownloader
98 * a resource downloader to use if actual download of the resource is needed
99 * @param options
100 * a set of options to adjust the download
85 *
86 * @param artifact the artifact to download
87 * @param resourceResolver a resource resolver to use if the artifact needs to be resolved to
88 * a Resource for downloading
89 * @param resourceDownloader a resource downloader to use if actual download of the resource is
90 * needed
91 * @param options a set of options to adjust the download
10192 * @return a report indicating how the download was performed
10293 */
103 public abstract ArtifactDownloadReport download(Artifact artifact,
104 ArtifactResourceResolver resourceResolver, ResourceDownloader resourceDownloader,
105 CacheDownloadOptions options);
94 ArtifactDownloadReport download(Artifact artifact,
95 ArtifactResourceResolver resourceResolver,
96 ResourceDownloader resourceDownloader,
97 CacheDownloadOptions options);
10698
10799 /**
108100 * Download some repository resource and put it in the cache.
109101 * <p>
110102 * If the cached version is considered enough up to date, no downloading is done.
111 *
112 * @param resource
113 * the resource of the file to put in cache
114 * @param name
115 * the descriptive name of the resource (helps while manually looking into the cache
116 * files)
117 * @param type
118 * the type of the resource (helps while manually looking into the cache files)
119 * @param extension
120 * the extension of the resource (helps while manually looking into the cache files)
121 * @param options
122 * a set of options to adjust the download
123 * @param repository
124 * the repository which resolve the content of the resource
103 *
104 * @param resource the resource of the file to put in cache
105 * @param name the descriptive name of the resource (helps while manually looking into the
106 * cache files)
107 * @param type the type of the resource (helps while manually looking into the cache files)
108 * @param extension the extension of the resource (helps while manually looking into the cache
109 * files)
110 * @param options a set of options to adjust the download
111 * @param repository the repository which resolve the content of the resource
125112 * @return a report indicating how the download was performed
126113 */
127 public ArtifactDownloadReport downloadRepositoryResource(Resource resource, String name,
128 String type, String extension, CacheResourceOptions options, Repository repository);
114 ArtifactDownloadReport downloadRepositoryResource(Resource resource, String name,
115 String type, String extension,
116 CacheResourceOptions options,
117 Repository repository);
129118
130119 /**
131120 * Caches an original module descriptor.
133122 * After this call, the original module descriptor file (with no modification nor conversion)
134123 * should be available as a local file.
135124 * </p>
136 *
137 * @param resolver
138 * the dependency resolver from which the cache request comes from
139 * @param orginalMetadataRef
140 * a resolved resource pointing to the remote original module descriptor
141 * @param dd
142 * the dependency descriptor for which the module descriptor should be cached
143 * @param requestedMetadataArtifact
144 * the module descriptor artifact as requested originally
145 * @param downloader
146 * a ResourceDownloader able to download the original module descriptor resource if
147 * required by this cache implementation
148 * @param options
149 * options to apply to cache this module descriptor
125 *
126 * @param resolver the dependency resolver from which the cache request comes
127 * from
128 * @param originalMetadataRef a resolved resource pointing to the remote original module
129 * descriptor
130 * @param dd the dependency descriptor for which the module descriptor
131 * should be cached
132 * @param requestedMetadataArtifact the module descriptor artifact as requested originally
133 * @param downloader a ResourceDownloader able to download the original module
134 * descriptor resource if required by this cache implementation
135 * @param options options to apply to cache this module descriptor
150136 * @return a {@link ResolvedModuleRevision} representing the local cached module descriptor, or
151 * null if it failed
152 * @throws ParseException
153 * if an exception occurred while parsing the module descriptor
137 * null if it failed
138 * @throws ParseException if an exception occurred while parsing the module descriptor
154139 */
155 public ResolvedModuleRevision cacheModuleDescriptor(DependencyResolver resolver,
156 ResolvedResource orginalMetadataRef, DependencyDescriptor dd,
157 Artifact requestedMetadataArtifact, ResourceDownloader downloader,
158 CacheMetadataOptions options) throws ParseException;
140 ResolvedModuleRevision cacheModuleDescriptor(DependencyResolver resolver,
141 ResolvedResource originalMetadataRef,
142 DependencyDescriptor dd,
143 Artifact requestedMetadataArtifact,
144 ResourceDownloader downloader,
145 CacheMetadataOptions options) throws ParseException;
159146
160147 /**
161148 * Stores a standardized version of an original module descriptor in the cache for later use.
162 *
163 * @param resolver
164 * the dependency resolver from which the cache request comes from
165 * @param orginalMetadataRef
166 * a resolved resource pointing to the remote original module descriptor
167 * @param requestedMetadataArtifact
168 * the module descriptor artifact as requested originally
169 * @param rmr
170 * the {@link ResolvedModuleRevision} representing the local cached module descriptor
171 * @param writer
172 * a {@link ModuleDescriptorWriter} able to write the module descriptor to a stream.
149 *
150 * @param resolver the dependency resolver from which the cache request comes
151 * from
152 * @param originalMetadataRef a resolved resource pointing to the remote original module
153 * descriptor
154 * @param requestedMetadataArtifact the module descriptor artifact as requested originally
155 * @param rmr the {@link ResolvedModuleRevision} representing the local
156 * cached module descriptor
157 * @param writer a {@link ModuleDescriptorWriter} able to write the module
158 * descriptor to a stream.
173159 */
174 public void originalToCachedModuleDescriptor(DependencyResolver resolver,
175 ResolvedResource orginalMetadataRef, Artifact requestedMetadataArtifact,
176 ResolvedModuleRevision rmr, ModuleDescriptorWriter writer);
160 void originalToCachedModuleDescriptor(DependencyResolver resolver,
161 ResolvedResource originalMetadataRef,
162 Artifact requestedMetadataArtifact,
163 ResolvedModuleRevision rmr, ModuleDescriptorWriter writer);
177164
178165 /**
179166 * Cleans the whole cache.
180167 */
181 public void clean();
168 void clean();
182169
183170 /**
184171 * Caches a dynamic revision constraint resolution.
185 *
186 * @param dynamicMrid
187 * the dynamic module revision id
188 * @param revision
189 * the resolved revision
172 *
173 * @param dynamicMrid the dynamic module revision id
174 * @param revision the resolved revision
175 * @deprecated See {@link #saveResolvedRevision(String, ModuleRevisionId, String)} which
176 * prevents cache + * thrashing when multiple resolvers store the same dynamicMrid
190177 */
191 public void saveResolvedRevision(ModuleRevisionId dynamicMrid, String revision);
178 @Deprecated
179 void saveResolvedRevision(ModuleRevisionId dynamicMrid, String revision);
180
181 /**
182 * Caches a dynamic revision constraint resolution for a specific resolver.
183 *
184 * @param resolverName the resolver in which this dynamic revision was resolved
185 * @param dynamicMrid the dynamic module revision id
186 * @param revision the resolved revision
187 */
188 void saveResolvedRevision(String resolverName, ModuleRevisionId dynamicMrid,
189 String revision);
192190
193191 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.text.ParseException;
2222 import java.util.Arrays;
2323 import java.util.HashSet;
24 import java.util.Iterator;
2524 import java.util.Set;
2625
2726 import org.apache.ivy.core.module.descriptor.Artifact;
5150 * are available in the corresponding resolver. Note that the check is not performed
5251 * recursively, i.e. if a dependency has itself dependencies badly described or not available,
5352 * this check will not discover it.
53 *
54 * @param ivyFile URL
55 * @param resolvername String
56 * @return boolean
5457 */
5558 public boolean check(URL ivyFile, String resolvername) {
5659 try {
6265 // check publications if possible
6366 if (resolvername != null) {
6467 DependencyResolver resolver = settings.getResolver(resolvername);
65 String[] confs = md.getConfigurationsNames();
66 Set artifacts = new HashSet();
67 for (int i = 0; i < confs.length; i++) {
68 artifacts.addAll(Arrays.asList(md.getArtifacts(confs[i])));
68 Set<Artifact> artifacts = new HashSet<>();
69 for (String conf : md.getConfigurationsNames()) {
70 artifacts.addAll(Arrays.asList(md.getArtifacts(conf)));
6971 }
70 for (Iterator iter = artifacts.iterator(); iter.hasNext();) {
71 Artifact art = (Artifact) iter.next();
72 if (!resolver.exists(art)) {
73 Message.info("declared publication not found: " + art);
72 for (Artifact artifact : artifacts) {
73 if (!resolver.exists(artifact)) {
74 Message.info("declared publication not found: " + artifact);
7475 result = false;
7576 }
7677 }
7778 }
7879
7980 // check dependencies
80 DependencyDescriptor[] dds = md.getDependencies();
8181 ResolveData data = new ResolveData(resolveEngine, new ResolveOptions());
82 for (int i = 0; i < dds.length; i++) {
82 for (DependencyDescriptor dd : md.getDependencies()) {
8383 // check master confs
84 String[] masterConfs = dds[i].getModuleConfigurations();
85 for (int j = 0; j < masterConfs.length; j++) {
86 if (!"*".equals(masterConfs[j].trim())
87 && md.getConfiguration(masterConfs[j]) == null) {
84 for (String masterConf : dd.getModuleConfigurations()) {
85 if (!"*".equals(masterConf.trim()) && md.getConfiguration(masterConf) == null) {
8886 Message.info("dependency required in non existing conf for " + ivyFile
89 + " \n\tin " + dds[i] + ": " + masterConfs[j]);
87 + " \n\tin " + dd + ": " + masterConf);
9088 result = false;
9189 }
9290 }
9391 // resolve
94 DependencyResolver resolver = settings
95 .getResolver(dds[i].getDependencyRevisionId());
96 ResolvedModuleRevision rmr = resolver.getDependency(dds[i], data);
92 DependencyResolver resolver = settings.getResolver(dd.getDependencyRevisionId());
93 ResolvedModuleRevision rmr = resolver.getDependency(dd, data);
9794 if (rmr == null) {
98 Message.info("dependency not found in " + ivyFile + ":\n\t" + dds[i]);
95 Message.info("dependency not found in " + ivyFile + ":\n\t" + dd);
9996 result = false;
10097 } else {
101 String[] depConfs = dds[i].getDependencyConfigurations(md
102 .getConfigurationsNames());
103 for (int j = 0; j < depConfs.length; j++) {
104 if (!Arrays.asList(rmr.getDescriptor().getConfigurationsNames()).contains(
105 depConfs[j])) {
98 for (String depConf : dd.getDependencyConfigurations(md.getConfigurationsNames())) {
99 if (!Arrays.asList(rmr.getDescriptor().getConfigurationsNames())
100 .contains(depConf)) {
106101 Message.info("dependency configuration is missing for " + ivyFile
107 + "\n\tin " + dds[i] + ": " + depConfs[j]);
102 + "\n\tin " + dd + ": " + depConf);
108103 result = false;
109104 }
110 Artifact[] arts = rmr.getDescriptor().getArtifacts(depConfs[j]);
111 for (int k = 0; k < arts.length; k++) {
112 if (!resolver.exists(arts[k])) {
105 for (Artifact art : rmr.getDescriptor().getArtifacts(depConf)) {
106 if (!resolver.exists(art)) {
113107 Message.info("dependency artifact is missing for " + ivyFile
114 + "\n\t in " + dds[i] + ": " + arts[k]);
108 + "\n\t in " + dd + ": " + art);
115109 result = false;
116110 }
117111 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.util.Arrays;
2424 import java.util.HashMap;
2525 import java.util.HashSet;
26 import java.util.Iterator;
2726 import java.util.Map;
2827 import java.util.Properties;
2928 import java.util.Set;
5251 * Delivers a resolved ivy file based upon last resolve call status. If resolve report file
5352 * cannot be found in cache, then it throws an IllegalStateException (maybe resolve has not been
5453 * called before ?).
55 *
54 *
5655 * @param revision
5756 * the revision to which the module should be delivered
5857 * @param destIvyPattern
5958 * the pattern to which the delivered ivy file should be written
6059 * @param options
6160 * the options with which deliver should be done
61 * @throws IOException if something goes wrong
62 * @throws ParseException if something goes wrong
6263 */
6364 public void deliver(String revision, String destIvyPattern, DeliverOptions options)
6465 throws IOException, ParseException {
8586 * Delivers a resolved ivy file based upon last resolve call status. If resolve report file
8687 * cannot be found in cache, then it throws an IllegalStateException (maybe resolve has not been
8788 * called before ?).
88 *
89 *
8990 * @param mrid
9091 * the module revision id of the module to deliver
9192 * @param revision
9495 * the pattern to which the delivered ivy file should be written
9596 * @param options
9697 * the options with which deliver should be done
98 * @throws IOException if something goes wrong
99 * @throws ParseException if something goes wrong
97100 */
98101 public void deliver(ModuleRevisionId mrid, String revision, String destIvyPattern,
99102 DeliverOptions options) throws IOException, ParseException {
110113 md.setResolvedPublicationDate(options.getPubdate());
111114
112115 // 2) parse resolvedRevisions From properties file
113 Map resolvedRevisions = new HashMap(); // Map (ModuleId -> String revision)
114 Map resolvedBranches = new HashMap(); // Map (ModuleId -> String branch)
115 Map dependenciesStatus = new HashMap(); // Map (ModuleId -> String status)
116 Map<ModuleRevisionId, String> resolvedRevisions = new HashMap<>(); // Map (ModuleId -> String revision)
117 Map<ModuleRevisionId, String> resolvedBranches = new HashMap<>(); // Map (ModuleId -> String branch)
118 Map<ModuleRevisionId, String> dependenciesStatus = new HashMap<>(); // Map (ModuleId -> String status)
116119 File ivyProperties = getCache().getResolvedIvyPropertiesInCache(mrid);
117120 if (!ivyProperties.exists()) {
118121 throw new IllegalStateException("ivy properties not found in cache for " + mrid
123126 props.load(in);
124127 in.close();
125128
126 for (Iterator iter = props.keySet().iterator(); iter.hasNext();) {
127 String depMridStr = (String) iter.next();
129 for (Object o : props.keySet()) {
130 String depMridStr = (String) o;
128131 String[] parts = props.getProperty(depMridStr).split(" ");
129132 ModuleRevisionId decodedMrid = ModuleRevisionId.decode(depMridStr);
130133 if (options.isResolveDynamicRevisions()) {
150153 }
151154
152155 // 3) use pdrResolver to resolve dependencies info
153 Map resolvedDependencies = new HashMap(); // Map (ModuleRevisionId -> String revision)
154 DependencyDescriptor[] dependencies = md.getDependencies();
155 for (int i = 0; i < dependencies.length; i++) {
156 String rev = (String) resolvedRevisions.get(dependencies[i].getDependencyRevisionId());
156 Map<ModuleRevisionId, String> resolvedDependencies = new HashMap<>();
157 // Map (ModuleRevisionId -> String revision)
158 for (DependencyDescriptor dependency : md.getDependencies()) {
159 String rev = resolvedRevisions.get(dependency.getDependencyRevisionId());
157160 if (rev == null) {
158 rev = dependencies[i].getDependencyRevisionId().getRevision();
159 }
160 String bra = (String) resolvedBranches.get(dependencies[i].getDependencyRevisionId());
161 rev = dependency.getDependencyRevisionId().getRevision();
162 }
163 String bra = resolvedBranches.get(dependency.getDependencyRevisionId());
161164 if (bra == null || "null".equals(bra)) {
162 bra = dependencies[i].getDependencyRevisionId().getBranch();
163 }
164 String depStatus = (String) dependenciesStatus.get(dependencies[i]
165 .getDependencyRevisionId());
166 ModuleRevisionId mrid2 = null;
167 if (bra == null) {
168 mrid2 = ModuleRevisionId
169 .newInstance(dependencies[i].getDependencyRevisionId(), rev);
170 } else {
171 mrid2 = ModuleRevisionId.newInstance(dependencies[i].getDependencyRevisionId(),
172 bra, rev);
173 }
174 resolvedDependencies.put(dependencies[i].getDependencyRevisionId(), options
175 .getPdrResolver().resolve(md, options.getStatus(), mrid2, depStatus));
165 bra = dependency.getDependencyRevisionId().getBranch();
166 }
167 String depStatus = dependenciesStatus.get(dependency.getDependencyRevisionId());
168 ModuleRevisionId mrid2 = (bra == null)
169 ? ModuleRevisionId.newInstance(dependency.getDependencyRevisionId(), rev)
170 : ModuleRevisionId.newInstance(dependency.getDependencyRevisionId(), bra, rev);
171 resolvedDependencies.put(dependency.getDependencyRevisionId(),
172 options.getPdrResolver().resolve(md, options.getStatus(), mrid2, depStatus));
176173 }
177174
178175 // 4) copy the source resolved ivy to the destination specified,
183180 Message.info("\tdelivering ivy file to " + publishedIvy);
184181
185182 String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md);
186 Set confsToRemove = new HashSet(Arrays.asList(md.getConfigurationsNames()));
183 Set<String> confsToRemove = new HashSet<>(Arrays.asList(md.getConfigurationsNames()));
187184 confsToRemove.removeAll(Arrays.asList(confs));
188185
189186 try {
198195 .setMerge(options.isMerge())
199196 .setMergedDescriptor(md)
200197 .setConfsToExclude(
201 (String[]) confsToRemove.toArray(new String[confsToRemove.size()]));
198 confsToRemove.toArray(new String[confsToRemove.size()]));
202199 if (!resolvedBranches.isEmpty()) {
203200 opts = opts.setResolvedBranches(resolvedBranches);
204201 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5454 /**
5555 * Returns an instance of DeliverOptions with options corresponding to default values taken from
5656 * the given settings.
57 *
57 *
5858 * @param settings
5959 * The settings to use to get default option values
6060 * @return a DeliverOptions instance ready to be used or customized
7373
7474 /**
7575 * Creates an instance of DeliverOptions with all options explicitly set.
76 * @param status String
77 * @param pubDate Date
78 * @param pdrResolver PublishingDependencyRevisionResolver
79 * @param validate boolean
80 * @param resolveDynamicRevisions boolean
81 * @param confs String[]
7682 */
7783 public DeliverOptions(String status, Date pubDate,
7884 PublishingDependencyRevisionResolver pdrResolver, boolean validate,
9298 * PublishingDependencyRevisionResolver can then do the delivering work for the dependency and
9399 * return the new (delivered) dependency info (with the delivered revision). Note that
94100 * PublishingDependencyRevisionResolver is only called for each <b>direct</b> dependency.
95 *
101 *
96102 * @return the pdrResolver that will be used during deliver
97103 */
98104 public PublishingDependencyRevisionResolver getPdrResolver() {
106112 * PublishingDependencyRevisionResolver can then do the delivering work for the dependency and
107113 * return the new (delivered) dependency info (with the delivered revision). Note that
108114 * PublishingDependencyRevisionResolver is only called for each <b>direct</b> dependency.
109 *
115 *
116 * @param pdrResolver PublishingDependencyRevisionResolver
110117 * @return the instance of DeliverOptions on which the method has been called, for easy method
111118 * chaining
112119 */
154161 /**
155162 * Returns the status to which the module should be delivered, or null if the current status
156163 * should be kept.
157 *
164 *
158165 * @return the status to which the module should be delivered
159166 */
160167 public String getStatus() {
164171 /**
165172 * Sets the status to which the module should be delivered, use null if the current status
166173 * should be kept.
167 *
174 *
175 * @param status String
168176 * @return the instance of DeliverOptions on which the method has been called, for easy method
169177 * chaining
170178 */
175183
176184 /**
177185 * Returns the id of a previous resolve to use for delivering.
178 *
186 *
179187 * @return the id of a previous resolve
180188 */
181189 public String getResolveId() {
184192
185193 /**
186194 * Sets the id of a previous resolve to use for delivering.
187 *
195 *
188196 * @param resolveId
189197 * the id of a previous resolve
190198 * @return the instance of DeliverOptions on which the method has been called, for easy method
196204 }
197205
198206 /**
199 * Return the configurations which must be deliverd. Returns <tt>null</tt> if all configurations
200 * has to be deliverd. Attention: the returned array can contain wildcards!
201 *
207 * Return the configurations which must be delivered. Returns <tt>null</tt> if all
208 * configurations has to be delivered. Attention: the returned array can contain wildcards!
209 *
202210 * @return the configurations to deliver
203211 */
204212 public String[] getConfs() {
207215
208216 /**
209217 * Sets the configurations to deliver.
210 *
218 *
211219 * @param confs
212220 * the configurations to deliver
213221 * @return the instance of DeliverOptions on which the method has been called, for easy method
221229 /**
222230 * Returns the branch with which the Ivy file should be delivered, or <code>null</code> if
223231 * branch info shouldn't be changed.
224 *
232 *
225233 * @return the branch with which the Ivy file should be delivered
226234 */
227235 public String getPubBranch() {
230238
231239 /**
232240 * Sets the branch with which the Ivy file should be delivered.
233 *
241 *
234242 * @param pubBranch
235243 * the branch with which the Ivy file should be delivered
236244 * @return the instance of DeliverOptions on which the method has been called, for easy method
263271 return "status=" + status + " pubdate=" + pubdate + " validate=" + validate
264272 + " resolveDynamicRevisions=" + resolveDynamicRevisions + " merge=" + merge
265273 + " resolveId=" + resolveId + " pubBranch=" + pubBranch;
266
267274 }
268275
269276 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727 /**
2828 * Returns the revision of the dependency for the publishing of the 'published' module in
2929 * 'publishedStatus' status.
30 *
31 * @param published
32 * @param publishedStatus
33 * @param depMrid
34 * @param status
30 *
31 * @param published ModuleDescriptor
32 * @param publishedStatus ditto
33 * @param depMrid ModuleRevisionId
34 * @param status ditto
3535 * @return the revision of the dependency
3636 */
3737 String resolve(ModuleDescriptor published, String publishedStatus, ModuleRevisionId depMrid,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3636 addIvyListener(listener, new IvyEventFilter(eventName, null, null));
3737 }
3838
39 public void addIvyListener(IvyListener listener, Filter filter) {
39 public void addIvyListener(IvyListener listener, Filter<IvyEvent> filter) {
4040 listeners.add(IvyListener.class, new FilteredIvyListener(listener, filter));
4141 }
4242
4343 public void removeIvyListener(IvyListener listener) {
4444 listeners.remove(IvyListener.class, listener);
4545 IvyListener[] listeners = this.listeners.getListeners(IvyListener.class);
46 for (int i = 0; i < listeners.length; i++) {
47 if (listeners[i] instanceof FilteredIvyListener) {
48 if (listener.equals(((FilteredIvyListener) listeners[i]).getIvyListener())) {
49 this.listeners.remove(IvyListener.class, listeners[i]);
46 for (IvyListener listen : listeners) {
47 if (listen instanceof FilteredIvyListener) {
48 if (listener.equals(((FilteredIvyListener) listen).getIvyListener())) {
49 this.listeners.remove(IvyListener.class, listen);
5050 }
5151 }
5252 }
5353 }
5454
5555 public boolean hasIvyListener(IvyListener listener) {
56 return Arrays.asList(listeners.getListeners(IvyListener.class)).contains(listener);
56 IvyListener[] listeners = this.listeners.getListeners(IvyListener.class);
57 for (IvyListener listen : listeners) {
58 if (listen instanceof FilteredIvyListener) {
59 if (listener.equals(((FilteredIvyListener) listen).getIvyListener())) {
60 return true;
61 }
62 }
63 }
64 return false;
5765 }
5866
5967 public void fireIvyEvent(IvyEvent evt) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 public class FilteredIvyListener implements IvyListener {
2222 private IvyListener listener;
2323
24 private Filter filter;
24 private Filter<IvyEvent> filter;
2525
26 public FilteredIvyListener(IvyListener listener, Filter filter) {
26 public FilteredIvyListener(IvyListener listener, Filter<IvyEvent> filter) {
2727 this.listener = listener;
2828 this.filter = filter;
2929 }
3232 return listener;
3333 }
3434
35 public Filter getFilter() {
35 public Filter<IvyEvent> getFilter() {
3636 return filter;
3737 }
3838
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
2424 import org.apache.ivy.core.module.id.ModuleId;
2525 import org.apache.ivy.core.module.id.ModuleRevisionId;
26 import org.apache.ivy.util.StringUtils;
26
27 import static org.apache.ivy.util.StringUtils.joinArray;
2728
2829 /**
30 * <p>
2931 * The root of all ivy events Any ivy event knows which ivy instance triggered the event (the
3032 * source) and also has a name and a map of attributes. The name of the event represents the event
3133 * type, usually there is a one - one mapping between event names and IvyEvent subclass, even if
32 * this is not mandatory. Example: pre-resolve pre-resolve-dependency post-download The map of
33 * attributes is a Map from String keys to String values. It is especially useful to filter events,
34 * and to get some of their essential data in some context where access to Java types is not easy
35 * (in an ant build file, for example), Example: pre-resolve (organisation=foo, module=bar,
36 * revision=1.0, conf=default) post-download (organisation=foo, module=bar, revision=1.0,
37 * artifact=foo-test, type=jar, ext=jar)
34 * this is not mandatory. Example: <code>pre-resolve pre-resolve-dependency post-download</code>
35 * </p>
36 * <p>
37 * The map of attributes is a Map from String keys to String values. It is especially useful to
38 * filter events, and to get some of their essential data in some context where access to Java types
39 * is not easy (in an Ant build file, for example), Example: <code>pre-resolve (organisation=foo,
40 * module=bar, revision=1.0, conf=default) post-download (organisation=foo, module=bar,
41 * revision=1.0, artifact=foo-test, type=jar, ext=jar)</code>
42 * </p>
3843 */
3944 public class IvyEvent {
4045 private EventManager source;
4146
4247 private String name;
4348
44 private Map attributes = new HashMap();
49 private Map<String, String> attributes = new HashMap<>();
4550
4651 protected IvyEvent(String name) {
4752 this.source = IvyContext.getContext().getEventManager();
5055
5156 /**
5257 * Should only be called during event object construction, since events should be immutable
53 *
54 * @param key
55 * @param value
58 *
59 * @param key ditto
60 * @param value ditto
5661 */
5762 protected void addAttribute(String key, String value) {
5863 attributes.put(key, value);
7681 }
7782
7883 protected void addConfsAttribute(String[] confs) {
79 addAttribute("conf", StringUtils.join(confs, ", "));
84 addAttribute("conf", joinArray(confs, ", "));
8085 }
8186
82 protected void addAttributes(Map attributes) {
87 protected void addAttributes(Map<String, String> attributes) {
8388 this.attributes.putAll(attributes);
8489 }
8590
9297 }
9398
9499 /**
95 * Returns the attributes of this event, as a Map(String->String)
96 *
97 * @return the attributes of this event, as a Map(String->String)
100 * Returns the attributes of this event, as a Map(String,String)
101 *
102 * @return the attributes of this event, as a Map(String,String)
98103 */
99 public Map getAttributes() {
100 return new HashMap(attributes);
104 public Map<String, String> getAttributes() {
105 return new HashMap<>(attributes);
101106 }
102107
103108 public String toString() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 import org.apache.ivy.util.filter.NotFilter;
2626 import org.apache.ivy.util.filter.OrFilter;
2727
28 import java.util.ArrayList;
29 import java.util.List;
30
31 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
32 import static org.apache.ivy.util.StringUtils.splitToArray;
33
2834 /**
2935 * A filter implementation filtering {@link IvyEvent} based upon an event name and a filter
3036 * expression. The name will be matched against the event name using the {@link PatternMatcher} used
3339 * attribute values is done using the {@link PatternMatcher} used to construct this object. Here are
3440 * some examples:
3541 * <table>
42 * <caption>Filtering examples</caption>
3643 * <tr>
3744 * <td>expression</td>
3845 * <td>effect</td>
5966 * </tr>
6067 * </table>
6168 * Combination of these can be used, but no parentheses are supported right now, so only the default
62 * priority can be used. The priority order is this one: AND OR NOT = This means that artifact=foo
63 * AND ext=zip OR type=src will match event with artifact matching foo AND (ext matching zip OR type
64 * matching src)
65 *
69 * priority can be used. The priority order is this one: <code>AND OR NOT =</code> This means that
70 * <code>artifact=foo AND ext=zip OR type=src</code> will match event with artifact matching foo AND
71 * (ext matching zip OR type matching src)
72 *
6673 * @since 1.4
6774 */
68 public class IvyEventFilter implements Filter {
75 public class IvyEventFilter implements Filter<IvyEvent> {
6976 private static final String NOT = "NOT ";
7077
7178 private static final String OR = " OR ";
7481
7582 private PatternMatcher matcher;
7683
77 private Filter nameFilter;
84 private Filter<IvyEvent> nameFilter;
7885
79 private Filter attFilter;
86 private Filter<IvyEvent> attFilter;
8087
8188 public IvyEventFilter(String event, String filterExpression, PatternMatcher matcher) {
82 this.matcher = matcher == null ? ExactPatternMatcher.INSTANCE : matcher;
89 this.matcher = (matcher == null) ? ExactPatternMatcher.INSTANCE : matcher;
8390 if (event == null) {
84 nameFilter = NoFilter.INSTANCE;
91 nameFilter = NoFilter.instance();
8592 } else {
8693 final Matcher eventNameMatcher = this.matcher.getMatcher(event);
87 nameFilter = new Filter() {
88 public boolean accept(Object o) {
89 IvyEvent e = (IvyEvent) o;
94 nameFilter = new Filter<IvyEvent>() {
95 public boolean accept(IvyEvent e) {
9096 return eventNameMatcher.matches(e.getName());
9197 }
9298 };
9399 }
94 attFilter = filterExpression == null || filterExpression.trim().length() == 0 ? NoFilter.INSTANCE
95 : parseExpression(filterExpression);
100 if (isNullOrEmpty(filterExpression)) {
101 attFilter = NoFilter.instance();
102 } else {
103 attFilter = parseExpression(filterExpression);
104 }
96105 }
97106
98 private Filter parseExpression(String filterExpression) {
107 private Filter<IvyEvent> parseExpression(String filterExpression) {
99108 // expressions handled for the moment: (informal grammar)
100109 // EXP := SIMPLE_EXP | AND_EXP | OR_EXP | NOT_EXP
101110 // AND_EXP := EXP && EXP
109118 index = filterExpression.indexOf(OR);
110119 if (index == -1) {
111120 if (filterExpression.startsWith(NOT)) {
112 return new NotFilter(parseExpression(filterExpression.substring(NOT.length())));
121 return new NotFilter<>(parseExpression(filterExpression.substring(NOT.length())));
113122 } else {
114123 index = filterExpression.indexOf("=");
115124 if (index == -1) {
117126 + filterExpression + ": no equal sign found");
118127 }
119128 final String attname = filterExpression.substring(0, index).trim();
120 String[] values = filterExpression.substring(index + 1).trim().split(",");
121 final Matcher[] matchers = new Matcher[values.length];
122 for (int i = 0; i < values.length; i++) {
123 matchers[i] = matcher.getMatcher(values[i].trim());
129 final List<Matcher> matchers = new ArrayList<>();
130 for (String value : splitToArray(filterExpression.substring(index + 1))) {
131 matchers.add(matcher.getMatcher(value));
124132 }
125 return new Filter() {
126 public boolean accept(Object o) {
127 IvyEvent e = (IvyEvent) o;
128 String val = (String) e.getAttributes().get(attname);
133 return new Filter<IvyEvent>() {
134 public boolean accept(IvyEvent e) {
135 String val = e.getAttributes().get(attname);
129136 if (val == null) {
130137 return false;
131138 }
132 for (int i = 0; i < matchers.length; i++) {
133 if (matchers[i].matches(val)) {
139 for (Matcher matcher : matchers) {
140 if (matcher.matches(val)) {
134141 return true;
135142 }
136143 }
139146 };
140147 }
141148 } else {
142 return new OrFilter(parseExpression(filterExpression.substring(0, index)),
149 return new OrFilter<>(parseExpression(filterExpression.substring(0, index)),
143150 parseExpression(filterExpression.substring(index + OR.length())));
144151 }
145152 } else {
146 return new AndFilter(parseExpression(filterExpression.substring(0, index)),
153 return new AndFilter<>(parseExpression(filterExpression.substring(0, index)),
147154 parseExpression(filterExpression.substring(index + AND.length())));
148155 }
149156 }
150157
151 public boolean accept(Object o) {
152 if (!(o instanceof IvyEvent)) {
153 return false;
154 }
155 return nameFilter.accept(o) && attFilter.accept(o);
158 public boolean accept(IvyEvent e) {
159 return nameFilter.accept(e) && attFilter.accept(e);
156160 }
157161
158162 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.EventListener;
2020
2121 public interface IvyListener extends EventListener {
22 public void progress(IvyEvent event);
22 void progress(IvyEvent event);
2323 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 /**
2525 * Event fired after artifact publication has finished (possibly in error). Triggers registered on
2626 * {@link #NAME} will be notified of these events.
27 *
27 *
2828 * @see DependencyResolver#publish(Artifact, File, boolean)
2929 */
3030 public class EndArtifactPublishEvent extends PublishEvent {
31
32 private static final long serialVersionUID = -65690169431499422L;
3331
3432 public static final String NAME = "post-publish-artifact";
3533
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424
2525 /**
2626 * Base class for events fired during {@link DependencyResolver#publish(Artifact, File, boolean)}.
27 *
27 *
2828 * @see StartArtifactPublishEvent
2929 * @see EndArtifactPublishEvent
3030 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 /**
2525 * Event fired just before an artifact is published into a resolver. Triggers registered on
2626 * {@link #NAME} will be notified of these events.
27 *
27 *
2828 * @see DependencyResolver#publish(Artifact, File, boolean)
2929 */
3030 public class StartArtifactPublishEvent extends PublishEvent {
31
32 private static final long serialVersionUID = -1134274781039590219L;
3331
3432 public static final String NAME = "pre-publish-artifact";
3533
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6464 * dependency management. It's basically the time elapsed since the corresponding
6565 * {@link StartResolveDependencyEvent}
6666 * </p>
67 *
67 *
6868 * @return the time elapsed to resolve the dependency.
6969 */
7070 public long getDuration() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4646
4747 /**
4848 * Duration of the retrieve operation, in ms.
49 *
49 *
5050 * @return Duration of the retrieve operation, in ms.
5151 */
5252 public long getDuration() {
5555
5656 /**
5757 * Number of artifacts which were copied (or symlinked) during the retrieve
58 *
58 *
5959 * @return Number of artifacts which were copied during the retrieve.
6060 */
6161 public int getNbCopied() {
6464
6565 /**
6666 * Number of artifacts which were not copied since they were already present and up to date.
67 *
67 *
6868 * @return Number of artifacts which were not copied since they were already present and up to
6969 * date.
7070 */
7474
7575 /**
7676 * Total size of all copied (or symlinked) artifacts, in bytes.
77 *
77 *
7878 * @return Total size of all copied (or symlinked) artifacts, in bytes.
7979 */
8080 public long getTotalCopiedSize() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
7777
7878 // build module file declaring the dependency
7979 Message.info(":: installing " + mrid + " ::");
80 DependencyResolver oldDicator = resolveEngine.getDictatorResolver();
80 DependencyResolver oldDictator = resolveEngine.getDictatorResolver();
8181 boolean log = settings.logNotConvertedExclusionRule();
8282 try {
8383 settings.setLogNotConvertedExclusionRule(true);
9292 ExactPatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.INSTANCE,
9393 new NoConflictManager());
9494
95 for (int c = 0; c < options.getConfs().length; c++) {
96 final String[] depConfs = options.getConfs();
97
98 for (int j = 0; j < depConfs.length; j++) {
99 final String depConf = depConfs[j].trim();
100
101 if (MatcherHelper.isExact(matcher, mrid)) {
102 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, mrid,
103 false, false, options.isTransitive());
95 for (String dc : options.getConfs()) {
96 final String depConf = dc.trim();
97
98 if (MatcherHelper.isExact(matcher, mrid)) {
99 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md, mrid,
100 false, false, options.isTransitive());
101 dd.addDependencyConfiguration("default", depConf);
102 md.addDependency(dd);
103 } else {
104 for (ModuleRevisionId imrid : searchEngine.listModules(fromResolver, mrid, matcher)) {
105 Message.info("\tfound " + imrid + " to install: adding to the list");
106 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
107 imrid, false, false, options.isTransitive());
104108 dd.addDependencyConfiguration("default", depConf);
105109 md.addDependency(dd);
106 } else {
107 ModuleRevisionId[] mrids = searchEngine.listModules(fromResolver, mrid,
108 matcher);
109
110 for (int i = 0; i < mrids.length; i++) {
111 Message.info("\tfound " + mrids[i] + " to install: adding to the list");
112 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
113 mrids[i], false, false, options.isTransitive());
114 dd.addDependencyConfiguration("default", depConf);
115 md.addDependency(dd);
116 }
117110 }
118111 }
119112 }
133126
134127 // now that everything is in cache, we can publish all these modules
135128 Message.info(":: installing in " + to + " ::");
136 for (int i = 0; i < dependencies.length; i++) {
137 ModuleDescriptor depmd = dependencies[i].getDescriptor();
129 for (IvyNode dependency : dependencies) {
130 ModuleDescriptor depmd = dependency.getDescriptor();
138131 if (depmd != null) {
139132 ModuleRevisionId depMrid = depmd.getModuleRevisionId();
140133 Message.verbose("installing " + depMrid);
143136 toResolver.beginPublishTransaction(depMrid, options.isOverwrite());
144137
145138 // publish artifacts
146 ArtifactDownloadReport[] artifacts = report.getArtifactsReports(depMrid);
147 for (int j = 0; j < artifacts.length; j++) {
148 if (artifacts[j].getLocalFile() != null) {
149 toResolver.publish(artifacts[j].getArtifact(),
150 artifacts[j].getLocalFile(), options.isOverwrite());
139 for (ArtifactDownloadReport artifact : report.getArtifactsReports(depMrid)) {
140 if (artifact.getLocalFile() != null) {
141 toResolver.publish(artifact.getArtifact(), artifact.getLocalFile(),
142 options.isOverwrite());
151143 }
152144 }
153145
154146 // publish metadata
155 MetadataArtifactDownloadReport artifactDownloadReport = dependencies[i]
147 MetadataArtifactDownloadReport artifactDownloadReport = dependency
156148 .getModuleRevision().getReport();
157149 File localIvyFile = artifactDownloadReport.getLocalFile();
158150 toResolver.publish(depmd.getMetadataArtifact(), localIvyFile,
202194 // IVY-834: log the problems if there were any...
203195 Message.sumupProblems();
204196
205 resolveEngine.setDictatorResolver(oldDicator);
197 resolveEngine.setDictatorResolver(oldDictator);
206198 settings.setLogNotConvertedExclusionRule(log);
207199 }
208200 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828
2929 DependencyResolver getResolver(String from);
3030
31 Collection getResolverNames();
31 Collection<String> getResolverNames();
3232
3333 ReportOutputter[] getReportOutputters();
3434
4040
4141 PatternMatcher getMatcher(String matcherName);
4242
43 Collection getMatcherNames();
43 Collection<String> getMatcherNames();
4444
4545 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.core.install;
1818
19 import org.apache.ivy.core.module.descriptor.Artifact;
1920 import org.apache.ivy.plugins.matcher.PatternMatcher;
2021 import org.apache.ivy.util.filter.Filter;
2122 import org.apache.ivy.util.filter.FilterHelper;
3132
3233 private String[] confs = {"*"};
3334
34 private Filter artifactFilter = FilterHelper.NO_FILTER;
35 private Filter<Artifact> artifactFilter = FilterHelper.NO_FILTER;
3536
3637 private String matcherName = PatternMatcher.EXACT;
3738
6263 return this;
6364 }
6465
65 public Filter getArtifactFilter() {
66 public Filter<Artifact> getArtifactFilter() {
6667 return artifactFilter;
6768 }
6869
69 public InstallOptions setArtifactFilter(Filter artifactFilter) {
70 this.artifactFilter = artifactFilter == null ? FilterHelper.NO_FILTER : artifactFilter;
70 public InstallOptions setArtifactFilter(Filter<Artifact> artifactFilter) {
71 this.artifactFilter = (artifactFilter == null) ? FilterHelper.NO_FILTER : artifactFilter;
7172 return this;
7273 }
7374
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6161 return getId().getAttribute(attName);
6262 }
6363
64 public Map getAttributes() {
64 public Map<String, String> getAttributes() {
6565 return getId().getAttributes();
6666 }
6767
6969 return getId().getExtraAttribute(attName);
7070 }
7171
72 public Map getExtraAttributes() {
72 public Map<String, String> getExtraAttributes() {
7373 return getId().getExtraAttributes();
7474 }
7575
76 public Map getQualifiedExtraAttributes() {
76 public Map<String, String> getQualifiedExtraAttributes() {
7777 return getId().getQualifiedExtraAttributes();
7878 }
7979
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3434
3535 private ArtifactId id;
3636
37 private Collection confs = new ArrayList();
37 private final Collection<String> confs = new ArrayList<>();
3838
3939 private PatternMatcher patternMatcher;
4040
41 public AbstractIncludeExcludeRule(ArtifactId aid, PatternMatcher matcher, Map extraAttributes) {
41 public AbstractIncludeExcludeRule(ArtifactId aid, PatternMatcher matcher,
42 Map<String, String> extraAttributes) {
4243 super(null, extraAttributes);
4344 id = aid;
4445 patternMatcher = matcher;
6869
6970 /**
7071 * Add a configuration for this rule
71 *
72 * @param conf
72 *
73 * @param conf String
7374 */
7475 public void addConfiguration(String conf) {
7576 confs.add(conf);
8081 }
8182
8283 public String[] getConfigurations() {
83 return (String[]) confs.toArray(new String[confs.size()]);
84 return confs.toArray(new String[confs.size()]);
8485 }
8586
8687 public PatternMatcher getMatcher() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232
3333 /**
3434 * Returns the resolved module revision id for this artifact
35 *
35 *
3636 * @return the resolved module revision id.
3737 */
3838 ModuleRevisionId getModuleRevisionId();
3939
4040 /**
4141 * Returns the resolved publication date for this artifact
42 *
42 *
4343 * @return the resolved publication date. Never null.
4444 */
4545 Date getPublicationDate();
4646
4747 /**
4848 * Return the name of the artifact, generally 'part' of the basename of the file.
49 *
49 *
5050 * @return the name of the artifact. Never null.
5151 */
5252 String getName();
5353
5454 /**
5555 * Returns the type of the artifact, typically 'jar', 'source', 'javadoc', 'debian', ...
56 *
56 *
5757 * @return the type of the artifact. Never null.
5858 */
5959 String getType();
6161 /**
6262 * Retrieve the extension of the artifact. The extension is without dot (ie. 'jar' and not
6363 * '.jar')
64 *
64 *
6565 * @return the extension of the artifact. Never null.
6666 */
6767 String getExt();
6969 /**
7070 * Returns the url at which this artifact can be found independently of ivy configuration. This
7171 * can be null (and is usually for standard artifacts)
72 *
72 *
7373 * @return url at which this artifact can be found independently of ivy configuration
7474 */
7575 URL getUrl();
7676
7777 /**
7878 * Returns the list of configurations where this artifact is associated to.
79 *
79 *
8080 * @return the list of configuration this artifact is associated to. Never null.
8181 */
8282 String[] getConfigurations();
8383
8484 /**
8585 * Return the specific identifier of this artifact.
86 *
86 *
8787 * @return the id of the artifact
8888 */
8989 ArtifactRevisionId getId();
9191 /**
9292 * Returns true if this artifact represents a module metadata artifact, false if it's a
9393 * published artifact
94 *
94 *
9595 * @return true if this artifact represents a module metadata artifact, false if it's a
9696 * published artifact
9797 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.ArrayList;
2020 import java.util.Arrays;
2121 import java.util.Collection;
22 import java.util.Collections;
2223 import java.util.LinkedHashSet;
2324 import java.util.Map;
2425 import java.util.Set;
3637 public static final Visibility PRIVATE = new Visibility("private");
3738
3839 public static Visibility getVisibility(String name) {
39 if ("private".equals(name)) {
40 return PRIVATE;
41 } else if ("public".equals(name)) {
42 return PUBLIC;
43 } else {
44 throw new IllegalArgumentException("unknwon visibility " + name);
40 switch (name) {
41 case "private":
42 return PRIVATE;
43 case "public":
44 return PUBLIC;
45 default:
46 throw new IllegalArgumentException("unknown visibility " + name);
4547 }
4648 }
4749
5153 this.name = name;
5254 }
5355
56 @Override
5457 public String toString() {
5558 return name;
5659 }
5760 }
5861
59 public static Collection/* <Configuration> */findConfigurationExtending(String conf,
62 public static Collection<Configuration> findConfigurationExtending(String conf,
6063 Configuration[] confs) {
61 Collection extendingConfs = new ArrayList();
62 for (int i = 0; i < confs.length; i++) {
63 if (confs[i] != null && Arrays.asList(confs[i].getExtends()).contains(conf)) {
64 extendingConfs.add(confs[i]);
65 extendingConfs.addAll(findConfigurationExtending(confs[i].getName(), confs));
64 Collection<Configuration> extendingConfs = new ArrayList<>();
65 for (Configuration cf : confs) {
66 if (cf != null && Arrays.asList(cf.getExtends()).contains(conf)) {
67 extendingConfs.add(cf);
68 extendingConfs.addAll(findConfigurationExtending(cf.getName(), confs));
6669 }
6770 }
6871 return extendingConfs;
7275
7376 private String description;
7477
75 private String[] extendsFrom;
78 private Set<String> extendsFrom;
7679
7780 private Visibility visibility;
7881
8487
8588 /**
8689 * Creates a new configuration.
87 *
90 *
8891 * @param name
8992 * the name of the configuration
9093 */
9396 }
9497
9598 public Configuration(Configuration source, ModuleRevisionId sourceModule) {
96 this(source.getAttributes(), source.getQualifiedExtraAttributes(), source.getName(), source
97 .getVisibility(), source.getDescription(), source.getExtends(), source
98 .isTransitive(), source.getDeprecated(), sourceModule);
99 this(source.getAttributes(), source.getQualifiedExtraAttributes(), source.getName(),
100 source.getVisibility(), source.getDescription(), source.getExtends(),
101 source.isTransitive(), source.getDeprecated(), sourceModule);
99102 }
100103
101104 /**
102105 * Creates a new configuration.
103 *
106 *
104107 * @param name
105108 * the name of the configuration
106109 * @param visibility
119122 this(null, null, name, visibility, description, ext, transitive, deprecated, null);
120123 }
121124
122 private Configuration(Map attributes, Map extraAttributes, String name, Visibility visibility,
123 String description, String[] ext, boolean transitive, String deprecated,
124 ModuleRevisionId sourceModule) {
125 private Configuration(Map<String, String> attributes, Map<String, String> extraAttributes,
126 String name, Visibility visibility, String description, String[] exts,
127 boolean transitive, String deprecated, ModuleRevisionId sourceModule) {
125128 super(attributes, extraAttributes);
126129
127130 if (name == null) {
133136 this.name = name;
134137 this.visibility = visibility;
135138 this.description = description;
136 if (ext == null) {
137 extendsFrom = new String[0];
139 if (exts == null) {
140 extendsFrom = Collections.emptySet();
138141 } else {
139 extendsFrom = new String[ext.length];
140 for (int i = 0; i < ext.length; i++) {
141 extendsFrom[i] = ext[i].trim();
142 extendsFrom = new LinkedHashSet<>();
143 for (String ext : exts) {
144 extendsFrom.add(ext.trim());
142145 }
143146 }
144147 this.transitive = transitive;
148151
149152 /**
150153 * Returns the deprecation message, or <tt>null</tt> if not specified.
151 *
154 *
152155 * @return Returns the deprecation message.
153156 */
154157 public String getDeprecated() {
166169 * @return Returns the extends. May be empty, but never null.
167170 */
168171 public String[] getExtends() {
169 return extendsFrom;
172 return extendsFrom.toArray(new String[extendsFrom.size()]);
170173 }
171174
172175 /**
194197 return sourceModule;
195198 }
196199
200 @Override
197201 public String toString() {
198202 return name;
199203 }
200204
205 @Override
201206 public boolean equals(Object obj) {
202 if (!(obj instanceof Configuration)) {
203 return false;
204 }
205 return ((Configuration) obj).getName().equals(getName());
206 }
207
207 return obj instanceof Configuration && ((Configuration) obj).getName().equals(getName());
208 }
209
210 @Override
208211 public int hashCode() {
209212 return getName().hashCode();
210213 }
217220
218221 Configuration[] configs = md.getConfigurations();
219222
220 Set newExtends = new LinkedHashSet();
221 for (int j = 0; j < extendsFrom.length; j++) {
222 if ("*".equals(extendsFrom[j])) {
223 addOther(configs, null, newExtends);
224 } else if ("*(public)".equals(extendsFrom[j])) {
225 addOther(configs, Visibility.PUBLIC, newExtends);
226 } else if ("*(private)".equals(extendsFrom[j])) {
227 addOther(configs, Visibility.PRIVATE, newExtends);
228 } else {
229 newExtends.add(extendsFrom[j]);
230 }
231 }
232
233 this.extendsFrom = (String[]) newExtends.toArray(new String[newExtends.size()]);
234 }
235
236 private void addOther(Configuration[] allConfigs, Visibility visibility, Set configs) {
237 for (int i = 0; i < allConfigs.length; i++) {
238 String currentName = allConfigs[i].getName();
223 Set<String> newExtends = new LinkedHashSet<>();
224 for (String extend : extendsFrom) {
225 switch (extend) {
226 case "*":
227 addOther(configs, null, newExtends);
228 break;
229 case "*(public)":
230 addOther(configs, Visibility.PUBLIC, newExtends);
231 break;
232 case "*(private)":
233 addOther(configs, Visibility.PRIVATE, newExtends);
234 break;
235 default:
236 newExtends.add(extend);
237 break;
238 }
239 }
240
241 this.extendsFrom = newExtends;
242 }
243
244 private void addOther(Configuration[] allConfigs, Visibility visibility, Set<String> configs) {
245 for (Configuration allConfig : allConfigs) {
246 String currentName = allConfig.getName();
239247 if (!name.equals(currentName)
240 && ((visibility == null) || visibility.equals(allConfigs[i].getVisibility()))) {
248 && (visibility == null || visibility.equals(allConfig.getVisibility()))) {
241249 configs.add(currentName);
242250 }
243251 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 public interface ConfigurationAware {
2424 /**
2525 * Returns the configurations of the module to which the object is attached
26 *
26 *
2727 * @return an array of configuration names to which the object is attached
2828 */
29 public String[] getConfigurations();
29 String[] getConfigurations();
3030
3131 /**
3232 * Tells this object that it will now be part of the given configuration
33 *
33 *
3434 * @param confName
3535 * the name of the configuration to which the object is now attached
3636 */
37 public void addConfiguration(String confName);
37 void addConfiguration(String confName);
3838 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.core.module.descriptor;
1818
19 import java.util.Iterator;
2019 import java.util.Map;
2120
2221 /**
2423 */
2524 public class ConfigurationGroup extends Configuration {
2625
27 private final Map/* <String, Configuration> */members;
26 private final Map<String, Configuration> members;
2827
29 public ConfigurationGroup(String confName, Map /* <String, Configuration> */members) {
28 public ConfigurationGroup(String confName, Map<String, Configuration> members) {
3029 super(confName);
3130 this.members = members;
3231 }
3635 * <p>
3736 * This list is built from the configuration name, if some of these configuration names have
3837 * actually not been recognized in the module, they will be <code>null</code> when accessed from
39 * {@link #getIntersectedConfiguration(String)}.
38 * {@link org.apache.ivy.core.module.descriptor.ConfigurationIntersection#getIntersectedConfiguration(String)}.
4039 * </p>
41 *
40 *
4241 * @return the list of configurations' names this object is an intersection of.
4342 */
4443 public String[] getMembersConfigurationNames() {
45 return (String[]) members.keySet().toArray(new String[members.size()]);
44 return members.keySet().toArray(new String[members.size()]);
4645 }
4746
4847 /**
4948 * Returns the {@link Configuration} object for the given conf name, or <code>null</code> if the
5049 * given conf name is not part of this group or if this conf name isn't defined in the module in
5150 * which this group has been built.
52 *
51 *
5352 * @param confName
5453 * the name of the configuration to return.
5554 * @return the member {@link Configuration} object for the given conf name
5655 */
5756 public Configuration getMemberConfiguration(String confName) {
58 return (Configuration) members.get(confName);
57 return members.get(confName);
5958 }
6059
6160 public Visibility getVisibility() {
62 for (Iterator it = members.values().iterator(); it.hasNext();) {
63 Configuration c = (Configuration) it.next();
61 for (Configuration c : members.values()) {
6462 if (c != null && Visibility.PRIVATE.equals(c.getVisibility())) {
6563 return Visibility.PRIVATE;
6664 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.core.module.descriptor;
1818
19 import java.util.Iterator;
2019 import java.util.Map;
2120
2221 /**
2423 */
2524 public class ConfigurationIntersection extends Configuration {
2625
27 private final Map/* <String, Configuration> */intersectedConfs;
26 private final Map<String, Configuration> intersectedConfs;
2827
2928 public ConfigurationIntersection(String confName,
30 Map /* <String, Configuration> */intersectedConfs) {
29 Map<String, Configuration> intersectedConfs) {
3130 super(confName);
3231 this.intersectedConfs = intersectedConfs;
3332 }
3938 * actually not been recognized in the module, they will be <code>null</code> when accessed from
4039 * {@link #getIntersectedConfiguration(String)}.
4140 * </p>
42 *
41 *
4342 * @return the list of configurations' names this object is an intersection of.
4443 */
4544 public String[] getIntersectedConfigurationNames() {
46 return (String[]) intersectedConfs.keySet().toArray(new String[intersectedConfs.size()]);
45 return intersectedConfs.keySet().toArray(new String[intersectedConfs.size()]);
4746 }
4847
4948 /**
5049 * Returns the intersected {@link Configuration} object for the given conf name, or
5150 * <code>null</code> if the given conf name is not part of this intersection or if this conf
5251 * name isn't defined in the module in which this intersection has been built.
53 *
52 *
5453 * @param confName
5554 * the name of the configuration to return.
5655 * @return the intersected {@link Configuration} object for the given conf name
5756 */
5857 public Configuration getIntersectedConfiguration(String confName) {
59 return (Configuration) intersectedConfs.get(confName);
58 return intersectedConfs.get(confName);
6059 }
6160
6261 public Visibility getVisibility() {
63 for (Iterator it = intersectedConfs.values().iterator(); it.hasNext();) {
64 Configuration c = (Configuration) it.next();
62 for (Configuration c : intersectedConfs.values()) {
6563 if (c != null && Visibility.PRIVATE.equals(c.getVisibility())) {
6664 return Visibility.PRIVATE;
6765 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
8383 }
8484
8585 public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, String name, String type,
86 String ext, Map extraAttributes) {
86 String ext, Map<String, String> extraAttributes) {
8787 this(mrid, publicationDate, name, type, ext, null, extraAttributes);
8888 }
8989
9090 public DefaultArtifact(ModuleRevisionId mrid, Date publicationDate, String name, String type,
91 String ext, URL url, Map extraAttributes) {
91 String ext, URL url, Map<String, String> extraAttributes) {
9292 this(ArtifactRevisionId.newInstance(mrid, name, type, ext, extraAttributes),
9393 publicationDate, url, false);
9494 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 public class DefaultDependencyArtifactDescriptor extends UnmodifiableExtendableItem implements
2929 DependencyArtifactDescriptor, ConfigurationAware {
3030
31 private Collection confs = new ArrayList();
31 private final Collection<String> confs = new ArrayList<>();
3232
3333 private URL url;
3434
4141 private DependencyDescriptor dd;
4242
4343 /**
44 * @param dd
45 * @param name
46 * @param type
47 * @param url
44 * @param dd DependencyDescriptor
45 * @param name ditto
46 * @param type ditto
47 * @param ext ditto
48 * @param url ditto
49 * @param extraAttributes ditto
4850 */
4951 public DefaultDependencyArtifactDescriptor(DependencyDescriptor dd, String name, String type,
50 String ext, URL url, Map extraAttributes) {
52 String ext, URL url, Map<String, String> extraAttributes) {
5153 super(null, extraAttributes);
5254 Checks.checkNotNull(dd, "dd");
5355 Checks.checkNotNull(name, "name");
8284
8385 /**
8486 * Add a configuration for this artifact.
85 *
86 * @param conf
87 *
88 * @param conf ditto
8789 */
8890 public void addConfiguration(String conf) {
8991 confs.add(conf);
106108 }
107109
108110 public String[] getConfigurations() {
109 return (String[]) confs.toArray(new String[confs.size()]);
111 return confs.toArray(new String[confs.size()]);
110112 }
111113
112114 public URL getUrl() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.Collection;
2222 import java.util.Collections;
2323 import java.util.HashSet;
24 import java.util.Iterator;
2524 import java.util.LinkedHashMap;
2625 import java.util.LinkedHashSet;
2726 import java.util.List;
5655 * descriptor in the system namespace. <i>Note that exclude rules are not converted in system
5756 * namespace, because they aren't transformable (the name space hasn't the ability to convert
5857 * regular expressions). However, method doesExclude will work with system artifacts.</i>
59 *
60 * @param dd
61 * @param ns
62 * @return
58 *
59 * @param dd DependencyDescriptor
60 * @param ns Namespace
61 * @return DependencyDescriptor
6362 */
6463 public static DependencyDescriptor transformInstance(DependencyDescriptor dd, Namespace ns) {
6564 NamespaceTransformer t = ns.getToSystemTransformer();
7574 * Transforms a dependency descriptor using the given transformer. Note that no namespace info
7675 * will be attached to the transformed dependency descriptor, so calling doesExclude is not
7776 * recommended (doesExclude only works when namespace is properly set)
78 *
79 * @param dd
80 * @param t
81 * @return
77 *
78 * @param dd DependencyDescriptor
79 * @param t NamespaceTransformer
80 * @param fromSystem boolean
81 * @return DefaultDependencyDescriptor
8282 */
8383 public static DefaultDependencyDescriptor transformInstance(DependencyDescriptor dd,
8484 NamespaceTransformer t, boolean fromSystem) {
9999 if (moduleConfs.length == 1 && "*".equals(moduleConfs[0])) {
100100 if (dd instanceof DefaultDependencyDescriptor) {
101101 DefaultDependencyDescriptor ddd = (DefaultDependencyDescriptor) dd;
102 newdd.confs = new LinkedHashMap(ddd.confs);
103 newdd.setExcludeRules(new LinkedHashMap(ddd.getExcludeRules()));
104 newdd.setIncludeRules(new LinkedHashMap(ddd.getIncludeRules()));
105 newdd.setDependencyArtifacts(new LinkedHashMap(ddd.getDependencyArtifacts()));
102 newdd.confs = new LinkedHashMap<>(ddd.confs);
103 newdd.setExcludeRules(new LinkedHashMap<>(ddd.getExcludeRules()));
104 newdd.setIncludeRules(new LinkedHashMap<>(ddd.getIncludeRules()));
105 newdd.setDependencyArtifacts(new LinkedHashMap<>(ddd.getDependencyArtifacts()));
106106 } else {
107107 throw new IllegalArgumentException(
108108 "dependency descriptor transformation does not support * module confs "
109109 + "with descriptors which aren't DefaultDependencyDescriptor");
110110 }
111111 } else {
112 for (int i = 0; i < moduleConfs.length; i++) {
113 newdd.confs.put(moduleConfs[i],
114 new ArrayList(Arrays.asList(dd.getDependencyConfigurations(moduleConfs[i]))));
115 newdd.getExcludeRules().put(moduleConfs[i],
116 new ArrayList(Arrays.asList(dd.getExcludeRules(moduleConfs[i]))));
117 newdd.getIncludeRules().put(moduleConfs[i],
118 new ArrayList(Arrays.asList(dd.getIncludeRules(moduleConfs[i]))));
119 newdd.getDependencyArtifacts().put(moduleConfs[i],
120 new ArrayList(Arrays.asList(dd.getDependencyArtifacts(moduleConfs[i]))));
112 for (String moduleConf : moduleConfs) {
113 newdd.confs.put(moduleConf,
114 new ArrayList<>(Arrays.asList(dd.getDependencyConfigurations(moduleConf))));
115 newdd.getExcludeRules().put(moduleConf,
116 new ArrayList<>(Arrays.asList(dd.getExcludeRules(moduleConf))));
117 newdd.getIncludeRules().put(moduleConf,
118 new ArrayList<>(Arrays.asList(dd.getIncludeRules(moduleConf))));
119 newdd.getDependencyArtifacts().put(moduleConf,
120 new ArrayList<>(Arrays.asList(dd.getDependencyArtifacts(moduleConf))));
121121 }
122122 }
123123 if (fromSystem) {
130130
131131 private ModuleRevisionId dynamicRevId;
132132
133 private Map/* <String,List<String>> */confs = new LinkedHashMap();
133 private Map<String, List<String>> confs = new LinkedHashMap<>();
134134
135135 // Map (String masterConf -> Collection(DependencyArtifactDescriptor))
136 private Map dependencyArtifacts; // initialized on demand only for memory consumption reason
136 // initialized on demand only for memory consumption reasons
137 private Map<String, Collection<DependencyArtifactDescriptor>> dependencyArtifacts;
137138
138139 // Map (String masterConf -> Collection(IncludeRule))
139 private Map includeRules; // initialized on demand only for memory consumption reason
140 // initialized on demand only for memory consumption reasons
141 private Map<String, Collection<IncludeRule>> includeRules;
140142
141143 // Map (String masterConf -> Collection(ExcludeRule))
142 private Map excludeRules; // initialized on demand only for memory consumption reason
144 // initialized on demand only for memory consumption reasons
145 private Map<String, Collection<ExcludeRule>> excludeRules;
143146
144147 /**
145148 * Used to indicate that this revision must be used in case of conflicts, independently of
187190 isTransitive = dd.isTransitive;
188191 namespace = dd.namespace;
189192 confs.putAll(dd.confs);
190 excludeRules = dd.excludeRules == null ? null : new LinkedHashMap(dd.excludeRules);
191 includeRules = dd.includeRules == null ? null : new LinkedHashMap(dd.includeRules);
192 dependencyArtifacts = dd.dependencyArtifacts == null ? null : new LinkedHashMap(
193 dd.dependencyArtifacts);
193 excludeRules = (dd.excludeRules == null) ? null : new LinkedHashMap<>(dd.excludeRules);
194 includeRules = (dd.includeRules == null) ? null : new LinkedHashMap<>(dd.includeRules);
195 dependencyArtifacts = (dd.dependencyArtifacts == null) ? null
196 : new LinkedHashMap<>(dd.dependencyArtifacts);
194197 sourceModule = dd.sourceModule;
195198 }
196199
234237 }
235238
236239 public String[] getModuleConfigurations() {
237 return (String[]) confs.keySet().toArray(new String[confs.keySet().size()]);
240 return confs.keySet().toArray(new String[confs.keySet().size()]);
238241 }
239242
240243 public String[] getDependencyConfigurations(String moduleConfiguration) {
251254 * extending one). Both moduleConfiguration and requestedConfiguration are configurations of the
252255 * caller, the array returned is composed of the required configurations of the dependency
253256 * described by this descriptor.
257 * </p>
258 *
259 * @param moduleConfiguration String
260 * @param requestedConfiguration String
261 * @return String[]
254262 */
255263 public String[] getDependencyConfigurations(String moduleConfiguration,
256264 String requestedConfiguration) {
258266 Configuration c = md.getConfiguration(moduleConfiguration);
259267 if (c instanceof ConfigurationIntersection) {
260268 ConfigurationIntersection intersection = (ConfigurationIntersection) c;
261 Set /* <String> */intersectedDepConfs = new HashSet();
262 String[] intersected = intersection.getIntersectedConfigurationNames();
263 for (int i = 0; i < intersected.length; i++) {
264 Collection depConfs = getDependencyConfigurationsIncludingExtending(
265 intersected[i], requestedConfiguration);
269 Set<String> intersectedDepConfs = new HashSet<>();
270 for (String intersect : intersection.getIntersectedConfigurationNames()) {
271 Collection<String> depConfs = getDependencyConfigurationsIncludingExtending(
272 intersect, requestedConfiguration);
266273 if (intersectedDepConfs.isEmpty()) {
267274 intersectedDepConfs.addAll(depConfs);
268275 } else {
273280 // nothing to do, intersection of 'something'
274281 // with 'everything' is 'something'
275282 } else {
276 Set /* <String> */intersectedDepConfsCopy = intersectedDepConfs;
277 intersectedDepConfs = new HashSet();
278 for (Iterator it = intersectedDepConfsCopy.iterator(); it.hasNext();) {
279 String intersectedDepConf = (String) it.next();
283 Set<String> intersectedDepConfsCopy = intersectedDepConfs;
284 intersectedDepConfs = new HashSet<>();
285 for (String intersectedDepConf : intersectedDepConfsCopy) {
280286 if (depConfs.contains(intersectedDepConf)) {
281287 // the conf is present in both sets,
282288 // so it is in the intersection
287293 * we do not handle special confs like *!sg or [cond]* in right hand
288294 * confs yet: it would require supporting parenthesis grouping in
289295 * configurations intersection interpretation
290 *
291 * for (Iterator it2 = depConfs.iterator(); it2.hasNext();) { String
292 * depConf = (String) it2.next(); if (depConf.startsWith("*")) { if
293 * (intersectedDepConf .indexOf("(" + depConf + ")") != -1) {
294 * intersectedDepConfs.add(intersectedDepConf); } else {
295 * intersectedDepConfs.add( "(" + intersectedDepConf + ")+(" +
296 * depConf + ")"); } } else if (intersectedDepConf.startsWith("*"))
297 * { if (depConf .indexOf("(" + intersectedDepConf + ")") != -1) {
298 * intersectedDepConfs.add(depConf); } else {
299 * intersectedDepConfs.add( depConf + "+" + intersectedDepConf); } }
296 *
297 * for (String depConf : depConfs) {
298 * if (depConf.startsWith("*")) {
299 * if (intersectedDepConf.contains("(" + depConf + ")")) {
300 * intersectedDepConfs.add(intersectedDepConf);
301 * } else {
302 * intersectedDepConfs.add("(" + intersectedDepConf + ")+(" + depConf + ")");
303 * }
304 * } else if (intersectedDepConf.startsWith("*")) {
305 * if (depConf.contains("(" + intersectedDepConf + ")")) {
306 * intersectedDepConfs.add(depConf);
307 * } else {
308 * intersectedDepConfs.add(depConf + "+" + intersectedDepConf);
309 * }
310 * }
300311 * }
301312 */
302313 }
303314 }
304315 }
305316 }
306 List confsList = (List) confs.get(moduleConfiguration);
317 List<String> confsList = confs.get(moduleConfiguration);
307318 if (confsList != null) {
308319 intersectedDepConfs.addAll(confsList);
309320 }
310321 if (intersectedDepConfs.isEmpty()) {
311 List defConfs = (List) confs.get("*");
322 List<String> defConfs = confs.get("*");
312323 if (defConfs != null) {
313 for (Iterator it = defConfs.iterator(); it.hasNext();) {
314 String mappedConf = (String) it.next();
324 for (String mappedConf : defConfs) {
315325 if (mappedConf != null && mappedConf.startsWith("@+")) {
316326 return new String[] {moduleConfiguration + mappedConf.substring(1)};
317327 } else if (mappedConf != null && mappedConf.equals("@")) {
320330 }
321331 }
322332 }
323 return (String[]) intersectedDepConfs
324 .toArray(new String[intersectedDepConfs.size()]);
333 return intersectedDepConfs.toArray(new String[intersectedDepConfs.size()]);
325334 } else if (c instanceof ConfigurationGroup) {
326335 ConfigurationGroup group = (ConfigurationGroup) c;
327 Set /* <String> */groupDepConfs = new HashSet();
328 String[] members = group.getMembersConfigurationNames();
329 for (int i = 0; i < members.length; i++) {
330 Collection depConfs = getDependencyConfigurationsIncludingExtending(members[i],
331 requestedConfiguration);
336 Set<String> groupDepConfs = new HashSet<>();
337 for (String member : group.getMembersConfigurationNames()) {
338 Collection<String> depConfs = getDependencyConfigurationsIncludingExtending(
339 member, requestedConfiguration);
332340 groupDepConfs.addAll(depConfs);
333341 }
334 return (String[]) groupDepConfs.toArray(new String[groupDepConfs.size()]);
335 }
336 }
337
338 List confsList = (List) confs.get(moduleConfiguration);
342 return groupDepConfs.toArray(new String[groupDepConfs.size()]);
343 }
344 }
345
346 List<String> confsList = confs.get(moduleConfiguration);
339347 if (confsList == null) {
340348 // there is no mapping defined for this configuration, add the 'other' mappings.
341 confsList = (List) confs.get("%");
342 }
343 List defConfs = (List) confs.get("*");
344 Collection ret = new LinkedHashSet();
349 confsList = confs.get("%");
350 }
351 List<String> defConfs = confs.get("*");
352 Collection<String> ret = new LinkedHashSet<>();
345353 if (confsList != null) {
346354 ret.addAll(confsList);
347355 }
348356 if (defConfs != null) {
349357 ret.addAll(defConfs);
350 }
351
352 Collection replacedRet = new LinkedHashSet();
353 for (Iterator iter = ret.iterator(); iter.hasNext();) {
354 String c = (String) iter.next();
358
359 // Fixes bugs IVY-1547, IVY-982 which have to do with
360 // negation (e.g. `*, !foo`) not working on the left side of the maps-to operator.
361 List<String> excludedConfs = confs.get("!" + moduleConfiguration);
362 if (excludedConfs != null)
363 ret.removeAll(excludedConfs);
364 }
365
366 Collection<String> replacedRet = new LinkedHashSet<>();
367 for (String c : ret) {
355368 String replacedConf = replaceSelfFallbackPattern(c, moduleConfiguration);
356369 if (replacedConf == null) {
357370 replacedConf = replaceThisFallbackPattern(c, requestedConfiguration);
363376 }
364377 ret = replacedRet;
365378 if (ret.remove("*")) {
366 StringBuffer r = new StringBuffer("*");
379 StringBuilder r = new StringBuilder("*");
367380 // merge excluded configurations as one conf like *!A!B
368 for (Iterator iter = ret.iterator(); iter.hasNext();) {
369 String c = (String) iter.next();
381 for (String c : ret) {
370382 if (c.startsWith("!")) {
371383 r.append(c);
372384 }
373385 }
374386 return new String[] {r.toString()};
375387 }
376 return (String[]) ret.toArray(new String[ret.size()]);
377 }
378
379 private Collection getDependencyConfigurationsIncludingExtending(String conf,
388 return ret.toArray(new String[ret.size()]);
389 }
390
391 private Collection<String> getDependencyConfigurationsIncludingExtending(String conf,
380392 String requestedConfiguration) {
381 Set/* <String> */allDepConfs = new LinkedHashSet();
382 allDepConfs
383 .addAll(Arrays.asList(getDependencyConfigurations(conf, requestedConfiguration)));
384
385 Collection extendingConfs = Configuration.findConfigurationExtending(conf,
393 Set<String> allDepConfs = new LinkedHashSet<>(Arrays.asList(getDependencyConfigurations(conf,
394 requestedConfiguration)));
395
396 Collection<Configuration> extendingConfs = Configuration.findConfigurationExtending(conf,
386397 md.getConfigurations());
387 for (Iterator it = extendingConfs.iterator(); it.hasNext();) {
388 Configuration extendingConf = (Configuration) it.next();
389 allDepConfs.addAll(Arrays.asList(getDependencyConfigurations(extendingConf.getName(),
390 requestedConfiguration)));
398 for (Configuration extendingConf : extendingConfs) {
399 allDepConfs.addAll(Arrays.asList(
400 getDependencyConfigurations(extendingConf.getName(), requestedConfiguration)));
391401 }
392402 return allDepConfs;
393403 }
405415
406416 /**
407417 * Replaces fallback patterns with correct values if fallback pattern exists.
408 *
418 *
409419 * @param pattern
410420 * pattern to look for
411421 * @param conf
420430 if (matcher.matches()) {
421431 String mappedConf = moduleConfiguration;
422432 if (matcher.group(1) != null) {
423 mappedConf = mappedConf + matcher.group(1);
433 mappedConf += matcher.group(1);
424434 }
425435 if (matcher.group(2) != null) {
426 mappedConf = mappedConf + matcher.group(2);
436 mappedConf += matcher.group(2);
427437 }
428438 return mappedConf;
429439 }
431441 }
432442
433443 public String[] getDependencyConfigurations(String[] moduleConfigurations) {
434 Set confs = new LinkedHashSet();
435 for (int i = 0; i < moduleConfigurations.length; i++) {
436 confs.addAll(Arrays.asList(getDependencyConfigurations(moduleConfigurations[i])));
444 Set<String> confs = new LinkedHashSet<>();
445 for (String moduleConfiguration : moduleConfigurations) {
446 confs.addAll(Arrays.asList(getDependencyConfigurations(moduleConfiguration)));
437447 }
438448 if (confs.contains("*")) {
439449 return new String[] {"*"};
440450 }
441 return (String[]) confs.toArray(new String[confs.size()]);
451 return confs.toArray(new String[confs.size()]);
442452 }
443453
444454 public DependencyArtifactDescriptor[] getDependencyArtifacts(String moduleConfiguration) {
445 Collection artifacts = getCollectionForConfiguration(moduleConfiguration,
446 dependencyArtifacts);
447 return (DependencyArtifactDescriptor[]) artifacts
448 .toArray(new DependencyArtifactDescriptor[artifacts.size()]);
455 Collection<DependencyArtifactDescriptor> artifacts = getCollectionForConfiguration(
456 moduleConfiguration, dependencyArtifacts);
457 return artifacts.toArray(new DependencyArtifactDescriptor[artifacts.size()]);
449458 }
450459
451460 public IncludeRule[] getIncludeRules(String moduleConfiguration) {
452 Collection rules = getCollectionForConfiguration(moduleConfiguration, includeRules);
453 return (IncludeRule[]) rules.toArray(new IncludeRule[rules.size()]);
461 Collection<IncludeRule> rules = getCollectionForConfiguration(moduleConfiguration,
462 includeRules);
463 return rules.toArray(new IncludeRule[rules.size()]);
454464 }
455465
456466 public ExcludeRule[] getExcludeRules(String moduleConfiguration) {
457 Collection rules = getCollectionForConfiguration(moduleConfiguration, excludeRules);
458 return (ExcludeRule[]) rules.toArray(new ExcludeRule[rules.size()]);
459 }
460
461 private Set getCollectionForConfiguration(String moduleConfiguration, Map collectionMap) {
467 Collection<ExcludeRule> rules = getCollectionForConfiguration(moduleConfiguration,
468 excludeRules);
469 return rules.toArray(new ExcludeRule[rules.size()]);
470 }
471
472 private <T> Set<T> getCollectionForConfiguration(String moduleConfiguration,
473 Map<String, Collection<T>> collectionMap) {
462474 if (collectionMap == null || collectionMap.isEmpty()) {
463 return Collections.EMPTY_SET;
464 }
465 Collection artifacts = (Collection) collectionMap.get(moduleConfiguration);
466 Collection defArtifacts = (Collection) collectionMap.get("*");
467 Set ret = new LinkedHashSet();
475 return Collections.emptySet();
476 }
477 Collection<T> artifacts = collectionMap.get(moduleConfiguration);
478 Collection<T> defArtifacts = collectionMap.get("*");
479 Set<T> ret = new LinkedHashSet<>();
468480 if (artifacts != null) {
469481 ret.addAll(artifacts);
470482 }
475487 }
476488
477489 public DependencyArtifactDescriptor[] getDependencyArtifacts(String[] moduleConfigurations) {
478 Set artifacts = new LinkedHashSet();
479 for (int i = 0; i < moduleConfigurations.length; i++) {
480 artifacts.addAll(Arrays.asList(getDependencyArtifacts(moduleConfigurations[i])));
481 }
482 return (DependencyArtifactDescriptor[]) artifacts
483 .toArray(new DependencyArtifactDescriptor[artifacts.size()]);
490 Set<DependencyArtifactDescriptor> artifacts = new LinkedHashSet<>();
491 for (String moduleConfiguration : moduleConfigurations) {
492 artifacts.addAll(Arrays.asList(getDependencyArtifacts(moduleConfiguration)));
493 }
494 return artifacts.toArray(new DependencyArtifactDescriptor[artifacts.size()]);
484495 }
485496
486497 public IncludeRule[] getIncludeRules(String[] moduleConfigurations) {
487 Set rules = new LinkedHashSet();
488 for (int i = 0; i < moduleConfigurations.length; i++) {
489 rules.addAll(Arrays.asList(getIncludeRules(moduleConfigurations[i])));
490 }
491 return (IncludeRule[]) rules.toArray(new IncludeRule[rules.size()]);
498 Set<IncludeRule> rules = new LinkedHashSet<>();
499 for (String moduleConfiguration : moduleConfigurations) {
500 rules.addAll(Arrays.asList(getIncludeRules(moduleConfiguration)));
501 }
502 return rules.toArray(new IncludeRule[rules.size()]);
492503 }
493504
494505 public ExcludeRule[] getExcludeRules(String[] moduleConfigurations) {
495 Set rules = new LinkedHashSet();
496 for (int i = 0; i < moduleConfigurations.length; i++) {
497 rules.addAll(Arrays.asList(getExcludeRules(moduleConfigurations[i])));
498 }
499 return (ExcludeRule[]) rules.toArray(new ExcludeRule[rules.size()]);
506 Set<ExcludeRule> rules = new LinkedHashSet<>();
507 for (String moduleConfiguration : moduleConfigurations) {
508 rules.addAll(Arrays.asList(getExcludeRules(moduleConfiguration)));
509 }
510 return rules.toArray(new ExcludeRule[rules.size()]);
500511 }
501512
502513 public DependencyArtifactDescriptor[] getAllDependencyArtifacts() {
503514 if (dependencyArtifacts == null) {
504515 return new DependencyArtifactDescriptor[0];
505516 }
506 Set ret = mergeAll(dependencyArtifacts);
507 return (DependencyArtifactDescriptor[]) ret.toArray(new DependencyArtifactDescriptor[ret
508 .size()]);
517 Set<DependencyArtifactDescriptor> ret = mergeAll(dependencyArtifacts);
518 return ret.toArray(new DependencyArtifactDescriptor[ret.size()]);
509519 }
510520
511521 public IncludeRule[] getAllIncludeRules() {
512522 if (includeRules == null) {
513523 return new IncludeRule[0];
514524 }
515 Set ret = mergeAll(includeRules);
516 return (IncludeRule[]) ret.toArray(new IncludeRule[ret.size()]);
525 Set<IncludeRule> ret = mergeAll(includeRules);
526 return ret.toArray(new IncludeRule[ret.size()]);
517527 }
518528
519529 public ExcludeRule[] getAllExcludeRules() {
520530 if (excludeRules == null) {
521531 return new ExcludeRule[0];
522532 }
523 Set ret = mergeAll(excludeRules);
524 return (ExcludeRule[]) ret.toArray(new ExcludeRule[ret.size()]);
525 }
526
527 private Set mergeAll(Map artifactsMap) {
528 Set ret = new LinkedHashSet();
529 for (Iterator it = artifactsMap.values().iterator(); it.hasNext();) {
530 Collection artifacts = (Collection) it.next();
533 Set<ExcludeRule> ret = mergeAll(excludeRules);
534 return ret.toArray(new ExcludeRule[ret.size()]);
535 }
536
537 private <T> Set<T> mergeAll(Map<String, Collection<T>> artifactsMap) {
538 Set<T> ret = new LinkedHashSet<>();
539 for (Collection<T> artifacts : artifactsMap.values()) {
531540 ret.addAll(artifacts);
532541 }
533542 return ret;
534543 }
535544
536545 public void addDependencyConfiguration(String masterConf, String depConf) {
537 if ((md != null) && !"*".equals(masterConf) && !"%".equals(masterConf)) {
546 if (md != null && !"*".equals(masterConf) && !"%".equals(masterConf)) {
538547 Configuration config;
539548 if (masterConf.startsWith("!")) {
540549 config = md.getConfiguration(masterConf.substring(1));
548557 }
549558 if (config instanceof ConfigurationGroup) {
550559 ConfigurationGroup group = (ConfigurationGroup) config;
551 String[] members = group.getMembersConfigurationNames();
552 for (int i = 0; i < members.length; i++) {
553 addDependencyConfiguration(members[i], depConf);
560 for (String member : group.getMembersConfigurationNames()) {
561 addDependencyConfiguration(member, depConf);
554562 }
555563 return;
556564 }
557565 }
558566
559 List confsList = (List) confs.get(masterConf);
567 List<String> confsList = confs.get(masterConf);
560568 if (confsList == null) {
561 confsList = new ArrayList();
569 confsList = new ArrayList<>();
562570 confs.put(masterConf, confsList);
563571 }
564572 if (!confsList.contains(depConf)) {
578586 addObjectToConfiguration(masterConf, rule, getExcludeRules());
579587 }
580588
581 private void addObjectToConfiguration(String callerConf, Object toAdd, Map confsMap) {
582 Collection col = (Collection) confsMap.get(callerConf);
589 private <T> void addObjectToConfiguration(String callerConf, T toAdd,
590 Map<String, Collection<T>> confsMap) {
591 Collection<T> col = confsMap.get(callerConf);
583592 if (col == null) {
584 col = new ArrayList();
593 col = new ArrayList<>();
585594 confsMap.put(callerConf, col);
586595 }
587596 col.add(toAdd);
589598
590599 /**
591600 * only works when namespace is properly set. The behaviour is not specified if namespace is not
592 * set
601 * set.
602 *
603 * @param moduleConfigurations String[]
604 * @param artifactId ditto
605 * @return boolean
593606 */
594607 public boolean doesExclude(String[] moduleConfigurations, ArtifactId artifactId) {
595608 if (namespace != null) {
596609 artifactId = NameSpaceHelper
597610 .transform(artifactId, namespace.getFromSystemTransformer());
598611 }
599 ExcludeRule[] rules = getExcludeRules(moduleConfigurations);
600 for (int i = 0; i < rules.length; i++) {
601 if (MatcherHelper.matches(rules[i].getMatcher(), rules[i].getId(), artifactId)) {
612 for (ExcludeRule rule : getExcludeRules(moduleConfigurations)) {
613 if (MatcherHelper.matches(rule.getMatcher(), rule.getId(), artifactId)) {
602614 return true;
603615 }
604616 }
606618 }
607619
608620 /**
609 * Returns true if this descriptor contains any exclusion rule
610 *
611 * @return
621 * @return true if this descriptor contains any exclusion rule
612622 */
613623 public boolean canExclude() {
614624 return excludeRules != null && !excludeRules.isEmpty();
642652 return revId.getAttribute(attName);
643653 }
644654
645 public Map getAttributes() {
655 public Map<String, String> getAttributes() {
646656 return revId.getAttributes();
647657 }
648658
650660 return revId.getExtraAttribute(attName);
651661 }
652662
653 public Map getExtraAttributes() {
663 public Map<String, String> getExtraAttributes() {
654664 return revId.getExtraAttributes();
655665 }
656666
657 public Map getQualifiedExtraAttributes() {
667 public Map<String, String> getQualifiedExtraAttributes() {
658668 return revId.getQualifiedExtraAttributes();
659669 }
660670
662672 return asSystem;
663673 }
664674
665 private void setDependencyArtifacts(Map dependencyArtifacts) {
675 private void setDependencyArtifacts(
676 Map<String, Collection<DependencyArtifactDescriptor>> dependencyArtifacts) {
666677 this.dependencyArtifacts = dependencyArtifacts;
667678 }
668679
669 private Map getDependencyArtifacts() {
680 private Map<String, Collection<DependencyArtifactDescriptor>> getDependencyArtifacts() {
670681 if (dependencyArtifacts == null) {
671 dependencyArtifacts = new LinkedHashMap();
682 dependencyArtifacts = new LinkedHashMap<>();
672683 }
673684 return dependencyArtifacts;
674685 }
675686
676 private void setIncludeRules(Map includeRules) {
687 private void setIncludeRules(Map<String, Collection<IncludeRule>> includeRules) {
677688 this.includeRules = includeRules;
678689 }
679690
680 private Map getIncludeRules() {
691 private Map<String, Collection<IncludeRule>> getIncludeRules() {
681692 if (includeRules == null) {
682 includeRules = new LinkedHashMap();
693 includeRules = new LinkedHashMap<>();
683694 }
684695 return includeRules;
685696 }
686697
687 private void setExcludeRules(Map excludeRules) {
698 private void setExcludeRules(Map<String, Collection<ExcludeRule>> excludeRules) {
688699 this.excludeRules = excludeRules;
689700 }
690701
691 private Map getExcludeRules() {
702 private Map<String, Collection<ExcludeRule>> getExcludeRules() {
692703 if (excludeRules == null) {
693 excludeRules = new LinkedHashMap();
704 excludeRules = new LinkedHashMap<>();
694705 }
695706 return excludeRules;
696707 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323
2424 public class DefaultExcludeRule extends AbstractIncludeExcludeRule implements ExcludeRule {
2525
26 public DefaultExcludeRule(ArtifactId aid, PatternMatcher matcher, Map extraAttributes) {
26 public DefaultExcludeRule(ArtifactId aid, PatternMatcher matcher, Map<String, String> extraAttributes) {
2727 super(aid, matcher, extraAttributes);
2828 }
2929
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.core.module.descriptor;
1818
1919 import java.util.ArrayList;
20 import java.util.Arrays;
2021 import java.util.List;
2122
2223 import org.apache.ivy.core.module.id.ModuleRevisionId;
2728
2829 private String location;
2930
30 private List extendsTypes;
31 private final List<String> extendsTypes;
3132
3233 private boolean local;
3334
4041 this.parent = parent;
4142 this.location = location;
4243 this.local = local;
43 this.extendsTypes = new ArrayList(types.length);
44 for (int i = 0; i < types.length; ++i) {
45 extendsTypes.add(types[i]);
46 }
44 this.extendsTypes = new ArrayList<>(types.length);
45 extendsTypes.addAll(Arrays.asList(types));
4746 }
4847
4948 public ModuleRevisionId getParentRevisionId() {
6362 }
6463
6564 public String[] getExtendsTypes() {
66 return (String[]) extendsTypes.toArray(new String[extendsTypes.size()]);
65 return extendsTypes.toArray(new String[extendsTypes.size()]);
6766 }
6867
6968 public boolean isAllInherited() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323
2424 public class DefaultIncludeRule extends AbstractIncludeExcludeRule implements IncludeRule {
2525
26 public DefaultIncludeRule(ArtifactId aid, PatternMatcher matcher, Map extraAttributes) {
26 public DefaultIncludeRule(ArtifactId aid, PatternMatcher matcher, Map<String, String> extraAttributes) {
2727 super(aid, matcher, extraAttributes);
2828 }
2929
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.util.Collection;
2525 import java.util.Date;
2626 import java.util.HashMap;
27 import java.util.Iterator;
2827 import java.util.LinkedHashMap;
2928 import java.util.LinkedHashSet;
3029 import java.util.List;
5352 import org.apache.ivy.plugins.version.VersionMatcher;
5453 import org.apache.ivy.util.Message;
5554
55 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
56
57 import static org.apache.ivy.core.module.descriptor.Configuration.findConfigurationExtending;
58
5659 /**
5760 *
5861 */
6770 DefaultModuleDescriptor moduleDescriptor = new DefaultModuleDescriptor(
6871 ModuleRevisionId.newInstance(mrid.getOrganisation(), mrid.getName() + "-caller",
6972 "working"), "integration", null, true);
70 for (int i = 0; i < confs.length; i++) {
71 moduleDescriptor.addConfiguration(new Configuration(confs[i]));
73 for (String conf : confs) {
74 moduleDescriptor.addConfiguration(new Configuration(conf));
7275 }
7376 moduleDescriptor.setLastModified(System.currentTimeMillis());
7477 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(moduleDescriptor, mrid,
7578 true, changing, transitive);
76 for (int j = 0; j < confs.length; j++) {
77 dd.addDependencyConfiguration(confs[j], confs[j]);
79 for (String conf : confs) {
80 dd.addDependencyConfiguration(conf, conf);
7881 }
7982 moduleDescriptor.addDependency(dd);
8083
8184 return moduleDescriptor;
8285 }
8386
84 public static DefaultModuleDescriptor newCallerInstance(ModuleRevisionId[] mrid,
87 public static DefaultModuleDescriptor newCallerInstance(ModuleRevisionId[] mrids,
8588 boolean transitive, boolean changing) {
8689 DefaultModuleDescriptor moduleDescriptor = new DefaultModuleDescriptor(
8790 ModuleRevisionId.newInstance("caller", "all-caller", "working"), "integration",
8891 null, true);
8992 moduleDescriptor.addConfiguration(new Configuration(DEFAULT_CONFIGURATION));
9093 moduleDescriptor.setLastModified(System.currentTimeMillis());
91 for (int i = 0; i < mrid.length; i++) {
94 for (ModuleRevisionId mrid : mrids) {
9295 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(moduleDescriptor,
93 mrid[i], true, changing, transitive);
96 mrid, true, changing, transitive);
9497 dd.addDependencyConfiguration(DEFAULT_CONFIGURATION, "*");
9598 moduleDescriptor.addDependency(dd);
9699 }
104107 null, true);
105108 moduleDescriptor.addConfiguration(new Configuration(DEFAULT_CONFIGURATION));
106109 if (artifacts != null && artifacts.length > 0) {
107 for (int i = 0; i < artifacts.length; i++) {
110 for (DependencyArtifactDescriptor artifact : artifacts) {
108111 moduleDescriptor.addArtifact(DEFAULT_CONFIGURATION,
109 new MDArtifact(moduleDescriptor, artifacts[i].getName(),
110 artifacts[i].getType(), artifacts[i].getExt(), artifacts[i].getUrl(),
111 artifacts[i].getExtraAttributes()));
112 new MDArtifact(moduleDescriptor, artifact.getName(), artifact.getType(),
113 artifact.getExt(), artifact.getUrl(), artifact.getExtraAttributes()));
112114 }
113115 } else {
114 moduleDescriptor.addArtifact(DEFAULT_CONFIGURATION, new MDArtifact(moduleDescriptor,
115 mrid.getName(), "jar", "jar"));
116 moduleDescriptor.addArtifact(DEFAULT_CONFIGURATION,
117 new MDArtifact(moduleDescriptor, mrid.getName(), "jar", "jar"));
116118 }
117119 moduleDescriptor.setLastModified(System.currentTimeMillis());
118120 return moduleDescriptor;
131133 /**
132134 * Transforms the given module descriptor of the given namespace and return a new module
133135 * descriptor in the system namespace. <i>Note that dependency exclude rules are not converted
134 * in system namespace, because they aren't transformable (the name space hasn't the ability to
136 * in system namespace, because they aren't transformable (the namespace lacks the ability to
135137 * convert regular expressions)</i>
136 *
137 * @param md
138 * @param ns
139 * @return
138 *
139 * @param md ModuleDescriptor
140 * @param ns Namespace
141 * @return ModuleDescriptor
140142 */
141143 public static ModuleDescriptor transformInstance(ModuleDescriptor md, Namespace ns) {
142144 NamespaceTransformer t = ns.getToSystemTransformer();
150152 nmd.publicationDate = md.getPublicationDate();
151153 nmd.resolvedPublicationDate = md.getResolvedPublicationDate();
152154
153 ExtendsDescriptor[] ed = md.getInheritedDescriptors();
154 for (int i = 0; i < ed.length; ++i) {
155 ModuleDescriptor parentMd = ed[i].getParentMd();
155 for (ExtendsDescriptor ed : md.getInheritedDescriptors()) {
156 ModuleDescriptor parentMd = ed.getParentMd();
156157 DefaultModuleDescriptor parentNmd = new DefaultModuleDescriptor(parentMd.getParser(),
157158 parentMd.getResource());
158159 parentNmd.revId = t.transform(parentMd.getModuleRevisionId());
161162 parentNmd.publicationDate = parentMd.getPublicationDate();
162163 parentNmd.resolvedPublicationDate = parentMd.getResolvedPublicationDate();
163164
164 nmd.inheritedDescriptors.add(new DefaultExtendsDescriptor(parentNmd, ed[i]
165 .getLocation(), ed[i].getExtendsTypes()));
166 }
167
168 DependencyDescriptor[] dd = md.getDependencies();
169 for (int i = 0; i < dd.length; i++) {
170 nmd.dependencies.add(NameSpaceHelper.toSystem(dd[i], ns));
171 }
172 Configuration[] confs = md.getConfigurations();
173 for (int i = 0; i < confs.length; i++) {
174 nmd.configurations.put(confs[i].getName(), confs[i]);
175 Artifact[] arts = md.getArtifacts(confs[i].getName());
176 for (int j = 0; j < arts.length; j++) {
177 nmd.addArtifact(confs[i].getName(), NameSpaceHelper.transform(arts[j], t));
165 nmd.inheritedDescriptors.add(new DefaultExtendsDescriptor(parentNmd, ed.getLocation(),
166 ed.getExtendsTypes()));
167 }
168
169 for (DependencyDescriptor dd : md.getDependencies()) {
170 nmd.dependencies.add(NameSpaceHelper.toSystem(dd, ns));
171 }
172
173 for (Configuration conf : md.getConfigurations()) {
174 final String confName = conf.getName();
175 nmd.configurations.put(confName, conf);
176 for (Artifact art : md.getArtifacts(confName)) {
177 nmd.addArtifact(confName, NameSpaceHelper.transform(art, t));
178178 }
179179 }
180180 nmd.setDefault(md.isDefault());
181181 if (md instanceof DefaultModuleDescriptor) {
182182 DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) md;
183 nmd.conflictManagers = (ModuleRules) dmd.conflictManagers.clone();
184 nmd.dependencyDescriptorMediators = (ModuleRules) dmd.dependencyDescriptorMediators
185 .clone();
183 nmd.conflictManagers = dmd.conflictManagers.clone();
184 nmd.dependencyDescriptorMediators = dmd.dependencyDescriptorMediators.clone();
186185 } else {
187186 Message.warn("transformed module descriptor is not a default module descriptor: "
188187 + "impossible to copy conflict manager and version mediation configuration: "
209208
210209 private Date resolvedPublicationDate;
211210
212 private List dependencies = new ArrayList(); // List (DependencyDescriptor)
213
214 private Map configurations = new LinkedHashMap(); // Map(String conf -> Configuration)
215
216 private Map artifactsByConf = new HashMap(); // Map (String conf -> Collection(Artifact))
217
218 private Collection artifacts = new LinkedHashSet(); // Collection(Artifact)
211 private List<DependencyDescriptor> dependencies = new ArrayList<>();
212
213 private Map<String, Configuration> configurations = new LinkedHashMap<>();
214
215 private Map<String, Collection<Artifact>> artifactsByConf = new HashMap<>();
216
217 private Collection<Artifact> artifacts = new LinkedHashSet<>();
219218
220219 // all artifacts could also be found in the artifactsByConf map, but here we can
221220 // preserve the order
222221
223222 private boolean isDefault = false;
224223
225 private ModuleRules conflictManagers = new ModuleRules();
226
227 private ModuleRules dependencyDescriptorMediators = new ModuleRules();
228
229 private List licenses = new ArrayList(); // List(License)
224 private ModuleRules<ConflictManager> conflictManagers = new ModuleRules<>();
225
226 private ModuleRules<DependencyDescriptorMediator> dependencyDescriptorMediators = new ModuleRules<>();
227
228 private List<License> licenses = new ArrayList<>();
230229
231230 private String homePage;
232231
246245
247246 private Resource resource;
248247
249 private List excludeRules = new ArrayList(); // List(ExcludeRule)
248 private List<ExcludeRule> excludeRules = new ArrayList<>();
250249
251250 private Artifact metadataArtifact;
252251
253 private List inheritedDescriptors = new ArrayList(); // List(ExtendsDescriptor)
254
255 private Map/* <String,String> */extraAttributesNamespaces = new LinkedHashMap();
256
257 private List<ExtraInfoHolder> extraInfos = new ArrayList<ExtraInfoHolder>();
252 private List<ExtendsDescriptor> inheritedDescriptors = new ArrayList<>();
253
254 private Map<String, String> extraAttributesNamespaces = new LinkedHashMap<>();
255
256 private List<ExtraInfoHolder> extraInfos = new ArrayList<>();
258257
259258 public DefaultModuleDescriptor(ModuleRevisionId id, String status, Date pubDate) {
260259 this(id, status, pubDate, false);
280279 /**
281280 * IMPORTANT : at least call setModuleRevisionId and setResolvedPublicationDate with instances
282281 * created by this constructor !
282 *
283 * @param parser ModuleDescriptorParser
284 * @param res Resource
283285 */
284286 public DefaultModuleDescriptor(ModuleDescriptorParser parser, Resource res) {
285287 this.parser = parser;
361363 /**
362364 * Artifact configurations are not used since added artifact may not be entirely completed, so
363365 * its configurations data may not be accurate
364 *
365 * @param conf
366 * @param artifact
366 *
367 * @param conf ditto
368 * @param artifact ditto
367369 */
368370 public void addArtifact(String conf, Artifact artifact) {
369371 Configuration c = getConfiguration(conf);
375377 }
376378 if (c instanceof ConfigurationGroup) {
377379 ConfigurationGroup group = (ConfigurationGroup) c;
378 String[] members = group.getMembersConfigurationNames();
379 for (int i = 0; i < members.length; i++) {
380 addArtifact(members[i], artifact);
380 for (String member : group.getMembersConfigurationNames()) {
381 addArtifact(member, artifact);
381382 }
382383 } else {
383 Collection artifacts = (Collection) artifactsByConf.get(conf);
384 Collection<Artifact> artifacts = artifactsByConf.get(conf);
384385 if (artifacts == null) {
385 artifacts = new ArrayList();
386 artifacts = new ArrayList<>();
386387 artifactsByConf.put(conf, artifacts);
387388 }
388389 artifacts.add(artifact);
403404 }
404405
405406 public ExtendsDescriptor[] getInheritedDescriptors() {
406 return (ExtendsDescriptor[]) inheritedDescriptors
407 .toArray(new ExtendsDescriptor[inheritedDescriptors.size()]);
407 return inheritedDescriptors.toArray(new ExtendsDescriptor[inheritedDescriptors.size()]);
408408 }
409409
410410 public Configuration[] getConfigurations() {
411 return (Configuration[]) configurations.values().toArray(
412 new Configuration[configurations.size()]);
411 return configurations.values().toArray(new Configuration[configurations.size()]);
413412 }
414413
415414 public String[] getConfigurationsNames() {
416 return (String[]) configurations.keySet().toArray(new String[configurations.size()]);
415 return configurations.keySet().toArray(new String[configurations.size()]);
417416 }
418417
419418 public String[] getPublicConfigurationsNames() {
420 List ret = new ArrayList();
421 for (Iterator iter = configurations.values().iterator(); iter.hasNext();) {
422 Configuration conf = (Configuration) iter.next();
423 if (conf.getVisibility() == Configuration.Visibility.PUBLIC) {
419 List<String> ret = new ArrayList<>();
420 for (Configuration conf : configurations.values()) {
421 if (PUBLIC.equals(conf.getVisibility())) {
424422 ret.add(conf.getName());
425423 }
426424 }
427 return (String[]) ret.toArray(new String[ret.size()]);
425 return ret.toArray(new String[ret.size()]);
428426 }
429427
430428 /**
431 * Returns the configuration object with the given name in the current module descriptor, null
429 * @param confName String
430 * @return the configuration object with the given name in the current module descriptor, null
432431 * if not found.
433432 */
434433 public Configuration getConfiguration(String confName) {
435 Configuration configuration = (Configuration) configurations.get(confName);
434 Configuration configuration = configurations.get(confName);
436435 if (configuration == null && confName != null) {
437436 // let's first check if the configuration is a conf group
438437 Matcher m = Pattern.compile("\\*\\[([^=]+)\\=([^\\]]+)\\]").matcher(confName);
441440 String attValue = m.group(2);
442441
443442 // this is a conf group, let's search for its members
444 Map /* <String,Configuration> */members = new LinkedHashMap();
445 for (Iterator it = configurations.values().iterator(); it.hasNext();) {
446 Configuration conf = (Configuration) it.next();
443 Map<String, Configuration> members = new LinkedHashMap<>();
444 for (Configuration conf : configurations.values()) {
447445 if (attValue.equals(conf.getAttribute(attName))) {
448446 members.put(conf.getName(), conf);
449447 }
456454 if (confs.length <= 1) {
457455 return null;
458456 }
459 Map /* <String,Configuration> */intersectedConfs = new LinkedHashMap();
460 for (int i = 0; i < confs.length; i++) {
461 Configuration c = (Configuration) configurations.get(confs[i]);
457 Map<String, Configuration> intersectedConfs = new LinkedHashMap<>();
458 for (String conf : confs) {
459 Configuration c = configurations.get(conf);
462460 if (c == null) {
463 Message.verbose("missing configuration '" + confs[i] + "' from intersection "
461 Message.verbose("missing configuration '" + conf + "' from intersection "
464462 + confName + " in " + this);
465463 return null;
466464 }
467 intersectedConfs.put(confs[i], c);
465 intersectedConfs.put(conf, c);
468466 }
469467 return new ConfigurationIntersection(confName, intersectedConfs);
470468 }
476474 if (c == null) {
477475 return new Artifact[0];
478476 }
479 Collection artifacts = (Collection) artifactsByConf.get(conf);
477 Collection<Artifact> artifacts = artifactsByConf.get(conf);
480478 if (c instanceof ConfigurationIntersection) {
481479 ConfigurationIntersection intersection = (ConfigurationIntersection) c;
482 String[] intersected = intersection.getIntersectedConfigurationNames();
483 Set/* <Artifact> */intersectedArtifacts = new LinkedHashSet();
484 for (int j = 0; j < intersected.length; j++) {
485 Collection arts = getArtifactsIncludingExtending(intersected[j]);
480 Set<Artifact> intersectedArtifacts = new LinkedHashSet<>();
481 for (String intersect : intersection.getIntersectedConfigurationNames()) {
482 Collection<Artifact> arts = getArtifactsIncludingExtending(intersect);
486483 if (intersectedArtifacts.isEmpty()) {
487484 intersectedArtifacts.addAll(arts);
488485 } else {
492489 if (artifacts != null) {
493490 intersectedArtifacts.addAll(artifacts);
494491 }
495 return (Artifact[]) intersectedArtifacts.toArray(new Artifact[intersectedArtifacts
496 .size()]);
492 return intersectedArtifacts.toArray(new Artifact[intersectedArtifacts.size()]);
497493 } else if (c instanceof ConfigurationGroup) {
498494 ConfigurationGroup group = (ConfigurationGroup) c;
499 String[] members = group.getMembersConfigurationNames();
500 Set/* <Artifact> */groupArtifacts = new LinkedHashSet();
501 for (int i = 0; i < members.length; i++) {
502 groupArtifacts.addAll(getArtifactsIncludingExtending(members[i]));
495 Set<Artifact> groupArtifacts = new LinkedHashSet<>();
496 for (String member : group.getMembersConfigurationNames()) {
497 groupArtifacts.addAll(getArtifactsIncludingExtending(member));
503498 }
504499 if (artifacts != null) {
505500 groupArtifacts.addAll(artifacts);
506501 }
507 return (Artifact[]) groupArtifacts.toArray(new Artifact[groupArtifacts.size()]);
502 return groupArtifacts.toArray(new Artifact[groupArtifacts.size()]);
508503 } else {
509504 if (artifacts == null) {
510505 return new Artifact[0];
511506 } else {
512 return (Artifact[]) artifacts.toArray(new Artifact[artifacts.size()]);
513 }
514 }
515 }
516
517 private Collection/* <Artifact> */getArtifactsIncludingExtending(String conf) {
518 Collection extendingConfs = Configuration.findConfigurationExtending(conf,
519 getConfigurations());
520 Set/* <Artifact> */artifacts = new LinkedHashSet();
521 Collection arts = (Collection) artifactsByConf.get(conf);
507 return artifacts.toArray(new Artifact[artifacts.size()]);
508 }
509 }
510 }
511
512 private Collection<Artifact> getArtifactsIncludingExtending(String conf) {
513 Set<Artifact> artifacts = new LinkedHashSet<>();
514 Collection<Artifact> arts = artifactsByConf.get(conf);
522515 if (arts != null) {
523516 artifacts.addAll(arts);
524517 }
525 for (Iterator it = extendingConfs.iterator(); it.hasNext();) {
526 Configuration extendingConf = (Configuration) it.next();
527 arts = (Collection) artifactsByConf.get(extendingConf.getName());
518 for (Configuration extendingConf : findConfigurationExtending(conf, getConfigurations())) {
519 arts = artifactsByConf.get(extendingConf.getName());
528520 if (arts != null) {
529521 artifacts.addAll(arts);
530522 }
533525 }
534526
535527 public Artifact[] getAllArtifacts() {
536 return (Artifact[]) artifacts.toArray(new Artifact[artifacts.size()]);
528 return artifacts.toArray(new Artifact[artifacts.size()]);
537529 }
538530
539531 public DependencyDescriptor[] getDependencies() {
540 return (DependencyDescriptor[]) dependencies.toArray(new DependencyDescriptor[dependencies
541 .size()]);
532 return dependencies.toArray(new DependencyDescriptor[dependencies.size()]);
542533 }
543534
544535 public boolean dependsOn(VersionMatcher matcher, ModuleDescriptor md) {
545 for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
546 DependencyDescriptor dd = (DependencyDescriptor) iter.next();
536 for (DependencyDescriptor dd : dependencies) {
547537 if (dd.getDependencyId().equals(md.getModuleRevisionId().getModuleId())) {
548538 if (md.getResolvedModuleRevisionId().getRevision() == null) {
549539 return true;
563553 }
564554 }
565555
556 @Override
566557 public int hashCode() {
567558 final int prime = 31;
568559 int result = 1;
570561 return result;
571562 }
572563
564 @Override
573565 public boolean equals(Object obj) {
574566 if (this == obj) {
575567 return true;
576568 }
577 if (obj == null) {
569 if (!(obj instanceof DefaultModuleDescriptor)) {
578570 return false;
579571 }
580 if (getClass() != obj.getClass()) {
581 return false;
582 }
583572 DefaultModuleDescriptor other = (DefaultModuleDescriptor) obj;
584 if (revId == null) {
585 if (other.revId != null) {
586 return false;
587 }
588 } else if (!revId.equals(other.revId)) {
589 return false;
590 }
591 return true;
592 }
593
573 return revId == null ? other.revId == null : revId.equals(other.revId);
574 }
575
576 @Override
594577 public String toString() {
595578 return "module: " + revId + " status=" + status + " publication=" + publicationDate
596579 + " configurations=" + configurations + " artifacts=" + artifactsByConf
604587 /**
605588 * regular expressions as explained in Pattern class may be used in ModuleId organisation and
606589 * name
607 *
608 * @param moduleId
609 * @param matcher
610 * @param resolverName
590 *
591 * @param moduleId ditto
592 * @param matcher PatternMatcher
593 * @param manager ConflictManager
611594 */
612595 public void addConflictManager(ModuleId moduleId, PatternMatcher matcher,
613596 ConflictManager manager) {
615598 }
616599
617600 public ConflictManager getConflictManager(ModuleId moduleId) {
618 return (ConflictManager) conflictManagers.getRule(moduleId);
601 return conflictManagers.getRule(moduleId);
619602 }
620603
621604 public void addDependencyDescriptorMediator(ModuleId moduleId, PatternMatcher matcher,
625608 }
626609
627610 public DependencyDescriptor mediate(DependencyDescriptor dd) {
628 Object[] mediators = dependencyDescriptorMediators.getRules(dd.getDependencyId());
629 for (int i = 0; i < mediators.length; i++) {
630 dd = ((DependencyDescriptorMediator) mediators[i]).mediate(dd);
611 for (DependencyDescriptorMediator mediator : dependencyDescriptorMediators.getRules(dd.getDependencyId())) {
612 dd = mediator.mediate(dd);
631613 }
632614 return dd;
633615 }
634616
635 public ModuleRules/* <DependencyDescriptorMediator> */getAllDependencyDescriptorMediators() {
636 return (ModuleRules) dependencyDescriptorMediators.clone();
617 public ModuleRules<DependencyDescriptorMediator> getAllDependencyDescriptorMediators() {
618 return dependencyDescriptorMediators.clone();
637619 }
638620
639621 public void addLicense(License license) {
641623 }
642624
643625 public License[] getLicenses() {
644 return (License[]) licenses.toArray(new License[licenses.size()]);
626 return licenses.toArray(new License[licenses.size()]);
645627 }
646628
647629 public String getHomePage() {
673655 }
674656
675657 public boolean isNamespaceUseful() {
676 for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
677 DependencyDescriptor dd = (DependencyDescriptor) iter.next();
658 for (DependencyDescriptor dd : dependencies) {
678659 if (dd.getAllExcludeRules().length > 0) {
679660 return true;
680661 }
687668 }
688669
689670 /**
690 * Throws an exception if the module descriptor is inconsistent For the moment, only extended
671 * Throws an exception if the module descriptor is inconsistent. For the moment, only extended
691672 * configurations existence and cycles are checked
692673 */
693674 public void check() {
694 Stack confs = new Stack();
695 for (Iterator iter = configurations.values().iterator(); iter.hasNext();) {
696 Configuration conf = (Configuration) iter.next();
697 String[] ext = conf.getExtends();
698 for (int i = 0; i < ext.length; i++) {
675 Stack<String> confs = new Stack<>();
676 for (Configuration conf : configurations.values()) {
677 for (String ext : conf.getExtends()) {
699678 confs.push(conf.getName());
700 checkConf(confs, ext[i].trim());
679 checkConf(confs, ext.trim());
701680 confs.pop();
702681 }
703682 }
704683 }
705684
706 private void checkConf(Stack confs, String confName) {
685 private void checkConf(Stack<String> confs, String confName) {
707686 int index = confs.indexOf(confName);
708687 if (index != -1) {
709 StringBuffer cycle = new StringBuffer();
688 StringBuilder cycle = new StringBuilder();
710689 for (; index < confs.size(); index++) {
711690 cycle.append(confs.get(index)).append(" => ");
712691 }
719698 throw new IllegalStateException("unknown configuration '" + confName
720699 + "'. It is extended by " + confs.get(confs.size() - 1));
721700 }
722 String[] ext = conf.getExtends();
723 for (int i = 0; i < ext.length; i++) {
701 for (String ext : conf.getExtends()) {
724702 confs.push(conf.getName());
725 checkConf(confs, ext[i].trim());
703 checkConf(confs, ext.trim());
726704 confs.pop();
727705 }
728706 }
755733 return resolvedRevId.getAttribute(attName);
756734 }
757735
758 public Map getAttributes() {
736 public Map<String, String> getAttributes() {
759737 return resolvedRevId.getAttributes();
760738 }
761739
763741 return resolvedRevId.getExtraAttribute(attName);
764742 }
765743
766 public Map getExtraAttributes() {
744 public Map<String, String> getExtraAttributes() {
767745 return resolvedRevId.getExtraAttributes();
768746 }
769747
770 public Map getQualifiedExtraAttributes() {
748 public Map<String, String> getQualifiedExtraAttributes() {
771749 return resolvedRevId.getQualifiedExtraAttributes();
772750 }
773751
788766 }
789767
790768 /**
791 * only works when namespace is properly set. The behaviour is not specified if namespace is not
792 * set
769 * Only works when namespace is properly set. The behaviour is not specified if namespace is
770 * not set.
771 *
772 * @param moduleConfigurations String[]
773 * @param artifactId ditto
774 * @return boolean
793775 */
794776 public boolean doesExclude(String[] moduleConfigurations, ArtifactId artifactId) {
795777 if (namespace != null) {
796778 artifactId = NameSpaceHelper
797779 .transform(artifactId, namespace.getFromSystemTransformer());
798780 }
799 ExcludeRule[] rules = getExcludeRules(moduleConfigurations);
800 for (int i = 0; i < rules.length; i++) {
801 if (MatcherHelper.matches(rules[i].getMatcher(), rules[i].getId(), artifactId)) {
781 for (ExcludeRule rule : getExcludeRules(moduleConfigurations)) {
782 if (MatcherHelper.matches(rule.getMatcher(), rule.getId(), artifactId)) {
802783 return true;
803784 }
804785 }
806787 }
807788
808789 public ExcludeRule[] getAllExcludeRules() {
809 return (ExcludeRule[]) excludeRules.toArray(new ExcludeRule[excludeRules.size()]);
790 return excludeRules.toArray(new ExcludeRule[excludeRules.size()]);
810791 }
811792
812793 public ExcludeRule[] getExcludeRules(String[] moduleConfigurations) {
813 Set rules = new LinkedHashSet();
814 for (Iterator iter = excludeRules.iterator(); iter.hasNext();) {
815 ExcludeRule rule = (ExcludeRule) iter.next();
794 Set<ExcludeRule> rules = new LinkedHashSet<>();
795 for (ExcludeRule rule : excludeRules) {
816796 String[] ruleConfs = rule.getConfigurations();
817797 if (containsAny(ruleConfs, moduleConfigurations)) {
818798 rules.add(rule);
819799 }
820800 }
821 return (ExcludeRule[]) rules.toArray(new ExcludeRule[rules.size()]);
801 return rules.toArray(new ExcludeRule[rules.size()]);
822802 }
823803
824804 private boolean containsAny(String[] arr1, String[] arr2) {
825 return new ArrayList(Arrays.asList(arr1)).removeAll(Arrays.asList(arr2));
826 }
827
828 public Map getExtraAttributesNamespaces() {
805 return new ArrayList<>(Arrays.asList(arr1)).removeAll(Arrays.asList(arr2));
806 }
807
808 public Map<String, String> getExtraAttributesNamespaces() {
829809 return extraAttributesNamespaces;
830810 }
831811
840820
841821 @Deprecated
842822 public Map<String, String> getExtraInfo() {
843 Map<String, String> map = new HashMap<String, String>();
823 Map<String, String> map = new HashMap<>();
844824 for (ExtraInfoHolder extraInfo : extraInfos) {
845825 populateExtraInfoMap(map, extraInfo);
846826 }
877857 }
878858 }
879859 return null;
880
881860 }
882861 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.core.module.descriptor;
18
19 import java.util.Date;
20
21 import org.apache.ivy.core.module.id.ModuleRevisionId;
22 import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
23 import org.apache.ivy.plugins.repository.Resource;
24
25 public class DefaultWorkspaceModuleDescriptor extends DefaultModuleDescriptor implements
26 WorkspaceModuleDescriptor {
27
28 public DefaultWorkspaceModuleDescriptor(ModuleDescriptorParser parser, Resource res) {
29 super(parser, res);
30 }
31
32 public DefaultWorkspaceModuleDescriptor(ModuleRevisionId id, String status, Date pubDate) {
33 super(id, status, pubDate);
34 }
35
36 public DefaultWorkspaceModuleDescriptor(ModuleRevisionId id, String status, Date pubDate,
37 boolean isDefault) {
38 super(id, status, pubDate, isDefault);
39 }
40
41 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 */
2727 public interface DependencyArtifactDescriptor extends ExtendableItem {
2828 /**
29 * Returns the dependency descriptor in which this dependency artifact descriptor is declared.
30 *
3129 * @return the dependency descriptor in which this dependency artifact descriptor is declared.
3230 */
33 public DependencyDescriptor getDependencyDescriptor();
31 DependencyDescriptor getDependencyDescriptor();
3432
3533 /**
36 * Returns the name of the artifact asked
37 *
38 * @return
34 * @return the name of the artifact asked
3935 */
40 public String getName();
36 String getName();
4137
4238 /**
43 * Returns the type of the artifact asked
44 *
45 * @return
39 * @return the type of the artifact asked
4640 */
47 public String getType();
41 String getType();
4842
4943 /**
50 * Returns the ext of the artifact asked
51 *
52 * @return
44 * @return the ext of the artifact asked
5345 */
54 public String getExt();
46 String getExt();
5547
5648 /**
57 * Returns the url to look this artifact at
58 *
59 * @return
49 * @return the url to look this artifact up at
6050 */
61 public URL getUrl();
51 URL getUrl();
6252
6353 /**
64 * Returns the configurations of the module in which the artifact is asked
65 *
66 * @return an array of configuration names in which the artifact is asked
54 * @return an array of configuration names of the module in which the artifact is asked
6755 */
68 public String[] getConfigurations();
56 String[] getConfigurations();
6957 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3333 * </p>
3434 * <p>
3535 * Then there is the dynamic constraint, which can either be the same as the default constraint, or
36 * the original dependency constraint when an Ivy file is delivered an published to a repository.
37 * This dynamic constraint is returned by {@link #getDynamicConstraintDependencyRevisionId()}, and
38 * corresponds to the <code>revconstraint</code> attribute in the Ivy file. In some resolve mode,
39 * this constraint can be used instead of the default dependency constraint when performing
40 * dependency resolution.
36 * the original dependency constraint when an Ivy file is delivered an published to a
37 * repository. This dynamic constraint is returned by
38 * {@link #getDynamicConstraintDependencyRevisionId()}, and corresponds to the
39 * <code>revconstraint</code> attribute in the Ivy file. In some resolve mode, this constraint can
40 * be used instead of the default dependency constraint when performing dependency resolution.
4141 * </p>
4242 */
4343 public interface DependencyDescriptor extends ExtendableItem, InheritableItem {
4646 /**
4747 * Used to indicate that this revision must be used in case of conflicts, independently of
4848 * conflicts manager. This only works for direct dependencies, and not transitive ones.
49 *
49 *
5050 * @return true if this dependency should be used, false if conflicts manager can do its work.
5151 */
5252 boolean isForce();
5656 * that the revision may have its artifacts modified without revision change. When new artifacts
5757 * are published a new ivy file should also be published with a new publication date to indicate
5858 * to ivy that artifacts have changed and that they should be downloaded again.
59 *
59 *
6060 * @return true if this dependency is a changing one
6161 */
6262 boolean isChanging();
6767
6868 /**
6969 * Returns the constraint on dependency this descriptor represents.
70 *
70 *
7171 * @return the constraint on dependency.
7272 */
7373 ModuleRevisionId getDependencyRevisionId();
7474
7575 /**
7676 * Returns the dynamic constraint on dependency this descriptor represents.
77 *
77 *
7878 * @return the dynamic constraint on dependency, or exact constraint if no dynamic constraint is
7979 * specified.
8080 */
110110
111111 /**
112112 * Returns true if
113 *
114 * @param moduleConfigurations
115 * @param artifactId
116 * @return
113 *
114 * @param moduleConfigurations ditto
115 * @param artifactId ditto
116 * @return boolean
117117 */
118118 boolean doesExclude(String[] moduleConfigurations, ArtifactId artifactId);
119119
120120 /**
121 * Returns true if this descriptor contains any exclusion rule
122 *
123121 * @return true if this descriptor contains any exclusion rule
124122 */
125 public boolean canExclude();
123 boolean canExclude();
126124
127125 DependencyDescriptor asSystem();
128126
129127 /**
130128 * Clones current dependency descriptor with another revision.
131 *
129 *
132130 * @param revision
133131 * the revision of the cloned dependency descriptor
134132 * @return the cloned dependency descriptor
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232 * information of any of its transitive dependencies, since it is called by dependency resolvers
3333 * before actually resolving a dependency.
3434 * </p>
35 *
35 *
3636 * @param dd
3737 * the dependency descriptor which should be mediated.
3838 * @return the mediated {@link DependencyDescriptor}, or the original
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828
2929 /**
3030 * Returns the id of the described artifact, without revision information
31 *
32 * @return
31 *
32 * @return ArtifactId
3333 */
34 public ArtifactId getId();
34 ArtifactId getId();
3535
3636 /**
3737 * Returns the configurations of the module in which the artifact is asked
38 *
38 *
3939 * @return an array of configuration names in which the artifact is asked
4040 */
41 public String[] getConfigurations();
41 String[] getConfigurations();
4242
4343 /**
4444 * Returns the matcher to use to know if an artifact match the current descriptor
45 *
46 * @return
45 *
46 * @return PatternMatcher
4747 */
48 public PatternMatcher getMatcher();
48 PatternMatcher getMatcher();
4949 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 */
2424 public interface ExtendsDescriptor {
2525
26 /** get the module revision id of the declared parent descriptor */
27 public ModuleRevisionId getParentRevisionId();
26 /**
27 * get the module revision id of the declared parent descriptor
28 *
29 * @return ModuleRevisionId
30 */
31 ModuleRevisionId getParentRevisionId();
2832
2933 /**
3034 * get the resolved revision id for {@link #getParentRevisionId}, see
3135 * {@link org.apache.ivy.core.module.descriptor.ModuleDescriptor#getResolvedModuleRevisionId()}
36 *
37 * @return ModuleRevisionId
3238 */
33 public ModuleRevisionId getResolvedParentRevisionId();
39 ModuleRevisionId getResolvedParentRevisionId();
3440
35 public ModuleDescriptor getParentMd();
41 ModuleDescriptor getParentMd();
3642
3743 /**
3844 * If there is an explicit path to check for the parent descriptor, return it. Otherwise returns
3945 * null.
46 *
47 * @return String
4048 */
41 public String getLocation();
49 String getLocation();
4250
4351 /**
4452 * Get the parts of the parent descriptor that are inherited. Default supported types are
4553 * <code>info</code>, <code>description</code>, <code>configurations</code>,
4654 * <code>dependencies</code>, and/or <code>all</code>. Ivy extensions may add support for
4755 * additional extends types.
56 *
57 * @return String[]
4858 */
49 public String[] getExtendsTypes();
59 String[] getExtendsTypes();
5060
51 /** @return true if the <code>all</code> extend type is specified, implying all other types */
52 public boolean isAllInherited();
61 /**
62 * @return true if the <code>all</code> extend type is specified, implying all other types
63 */
64 boolean isAllInherited();
5365
54 /** @return true if parent info attributes are inherited (organisation, branch, revision, etc) */
55 public boolean isInfoInherited();
66 /**
67 * @return true if parent info attributes are inherited (organisation, branch, revision, etc)
68 */
69 boolean isInfoInherited();
5670
57 /** @return true if parent description is inherited */
58 public boolean isDescriptionInherited();
71 /**
72 * @return true if parent description is inherited
73 */
74 boolean isDescriptionInherited();
5975
60 /** @return true if parent configurations are inherited */
61 public boolean areConfigurationsInherited();
76 /**
77 * @return true if parent configurations are inherited
78 */
79 boolean areConfigurationsInherited();
6280
63 /** @return true if parent dependencies are inherited */
64 public boolean areDependenciesInherited();
81 /**
82 * @return true if parent dependencies are inherited
83 */
84 boolean areDependenciesInherited();
6585
66 public boolean isLocal();
86 boolean isLocal();
6787 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525
2626 private String name;
2727
28 private Map<String, String> attributes = new LinkedHashMap<String, String>();
28 private Map<String, String> attributes = new LinkedHashMap<>();
2929
3030 private String content;
3131
32 private List<ExtraInfoHolder> nestedExtraInfoHolder = new ArrayList<ExtraInfoHolder>();
32 private List<ExtraInfoHolder> nestedExtraInfoHolder = new ArrayList<>();
3333
3434 public ExtraInfoHolder() {
3535
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import org.apache.ivy.util.extendable.ExtendableItem;
2222
2323 /**
24 * This describes a rule of inclusion. It is used to resctrict the artifacts and modules asked for a
24 * This describes a rule of inclusion. It is used to restrict the artifacts and modules asked for a
2525 * dependency, by including only modules and artifacts matching the rule
2626 */
2727 public interface IncludeRule extends ExtendableItem {
2828
2929 /**
3030 * Returns the id of the described artifact, without revision information
31 *
32 * @return
31 *
32 * @return ArtifactId
3333 */
34 public ArtifactId getId();
34 ArtifactId getId();
3535
3636 /**
3737 * Returns the configurations of the module in which the artifact is asked
38 *
38 *
3939 * @return an array of configuration names in which the artifact is asked
4040 */
41 public String[] getConfigurations();
41 String[] getConfigurations();
4242
4343 /**
4444 * Returns the matcher to use to know if an artifact match the current descriptor
45 *
46 * @return
45 *
46 * @return PatternMatcher
4747 */
48 public PatternMatcher getMatcher();
48 PatternMatcher getMatcher();
4949
5050 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020
2121 /**
2222 * Interface for elements that can be inherited from a parent descriptor by a child descriptor.
23 *
23 *
2424 * @see Configuration
2525 * @see DependencyDescriptor
2626 */
2929 * @return the module in which this item was actually defined, if different from the module in
3030 * which the item appears. May be null.
3131 */
32 public ModuleRevisionId getSourceModule();
32 ModuleRevisionId getSourceModule();
3333 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4242
4343 private String ext;
4444
45 private List/* <String> */confs = new ArrayList();
45 private final List<String> confs = new ArrayList<>();
4646
47 private Map extraAttributes = null;
47 private Map<String, String> extraAttributes = null;
4848
4949 private URL url;
5050
6060 }
6161
6262 public MDArtifact(ModuleDescriptor md, String name, String type, String ext, URL url,
63 Map extraAttributes) {
63 Map<String, String> extraAttributes) {
6464 if (md == null) {
6565 throw new NullPointerException("null module descriptor not allowed");
6666 }
108108 }
109109
110110 public String[] getConfigurations() {
111 return (String[]) confs.toArray(new String[confs.size()]);
111 return confs.toArray(new String[confs.size()]);
112112 }
113113
114114 public void addConfiguration(String conf) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4040 public interface ModuleDescriptor extends ExtendableItem, ArtifactInfo,
4141 DependencyDescriptorMediator {
4242
43 public static final String DEFAULT_CONFIGURATION = "default";
44
45 public static final String CALLER_ALL_CONFIGURATION = "all";
46
47 /**
48 * Returns true if this descriptor is a default one, i.e. one generated for a module not
49 * actually having one.
50 *
51 * @return
43 String DEFAULT_CONFIGURATION = "default";
44
45 String CALLER_ALL_CONFIGURATION = "all";
46
47 /**
48 * @return true if this descriptor is a default one, i.e. one generated for a module not
49 * actually having one.
5250 */
5351 boolean isDefault();
5452
5553 ModuleRevisionId getModuleRevisionId();
5654
5755 /**
58 * The module revision id returned here is the resolved one, i.e. it is never a latest one. If
59 * the revision has not been resolved, a null revision should be returned by getRevision() of
60 * the returned ModuleRevisionId. This revision must be the same as the module descriptor
61 * resolved revision id unless no module descriptor is defined
62 *
63 * @return
56 * @return the resolved module revision id; it is never the latest one. If the revision has not
57 * been resolved, a null revision should be returned by getRevision() of the returned
58 * ModuleRevisionId. This revision must be the same as the module descriptor resolved
59 * revision id unless no module descriptor is defined
6460 */
6561 ModuleRevisionId getResolvedModuleRevisionId();
6662
6763 /**
68 * This method update the resolved module revision id
69 *
70 * @param revId
64 * This method updates the resolved module revision id
65 *
66 * @param revId ModuleRevisionId
7167 */
7268 void setResolvedModuleRevisionId(ModuleRevisionId revId);
7369
7470 /**
75 * Get the list of parent descriptors imported via an &lt;extends&gt; element. Only directly
76 * imported descriptors are included; the parent's parents are not included.
71 * @return the list of parent descriptors imported via an &lt;extends&gt; element. Only directly
72 * imported descriptors are included; the parent's parents are not included.
7773 */
7874 ExtendsDescriptor[] getInheritedDescriptors();
7975
8076 /**
8177 * This method update the resolved publication date
82 *
83 * @param publicationDate
78 *
79 * @param publicationDate Date
8480 */
8581 void setResolvedPublicationDate(Date publicationDate);
8682
8783 String getStatus();
8884
8985 /**
90 * May be <code>null</code> if unknown in the descriptor itself.
91 *
92 * @return The publication date or <code>null</code> when not knwon.
86 * @return the publication date or null when not known in the descriptor itself.
9387 */
9488 Date getPublicationDate();
9589
9791 * The publication date of the module revision should be the date at which it has been
9892 * published, i.e. in general the date of any of its published artifacts, since all published
9993 * artifact of a module should follow the same publishing cycle.
94 *
95 * @return Date
10096 */
10197 Date getResolvedPublicationDate();
10298
10399 /**
104 * Returns all the configurations declared by this module as an array. This array is never empty
105 * (a 'default' conf is assumed when none is declared in the ivy file)
106 *
107 * @return all the configurations declared by this module as an array.
100 * @return all the configurations declared by this module as an array. This array is never empty
101 * (a 'default' conf is assumed when none is declared in the ivy file).
108102 */
109103 Configuration[] getConfigurations();
110104
115109 Artifact[] getArtifacts(String conf);
116110
117111 /**
118 * Returns all artifacts of this module, excluding the artifact corresponding to the module
119 * descriptor.
120 *
121 * @return all published artifacts of this module
112 * @return all published artifacts of this module, excluding the artifact corresponding to the
113 * module descriptor.
122114 * @see #getMetadataArtifact()
123115 */
124116 Artifact[] getAllArtifacts();
125117
126118 /**
127 * @retun The dependencies of the module. If there is no dependencies return an empty array (non
128 * null)
119 * @return The dependencies of the module. If there are no dependencies return an empty array
120 * (non null)
129121 */
130122 DependencyDescriptor[] getDependencies();
131123
132124 /**
133 * Returns true if the module described by this descriptor dependes directly upon the given
134 * module descriptor
135 *
136 * @param md
137 * @return
125 * @param matcher VersionMatcher
126 * @param md ModuleDescriptor
127 * @return true if the module described by this descriptor depends directly upon the given
128 * module descriptor
138129 */
139130 boolean dependsOn(VersionMatcher matcher, ModuleDescriptor md);
140131
141132 /**
142 * @param confName
143 * @return
133 * @param confName ditto
134 * @return Configuration
144135 */
145136 Configuration getConfiguration(String confName);
146137
147138 /**
148 * Returns the conflict manager to use for the given ModuleId, or <code>null</code> if no
149 * specific conflict manager is associated with the given module id in this module descriptor.
150 *
151 * @param id
152 * @return
139 * @param id ModuleId
140 * @return the conflict manager to use for the given ModuleId, or null if no specific conflict
141 * manager is associated with the given module id in this module descriptor.
153142 */
154143 ConflictManager getConflictManager(ModuleId id);
155144
156145 /**
157 * Returns the licenses of the module described by this descriptor
158 *
159 * @return
146 * @return the licenses of the module described by this descriptor
160147 */
161148 License[] getLicenses();
162149
170157 * Writes this module descriptor as an ivy file. If this descriptor was obtained through the
171158 * parsing of an ivy file, it should keep the layout of the file the most possible similar to
172159 * the original one.
173 *
160 *
174161 * @param ivyFile
175162 * the destination ivy file
163 * @throws ParseException if something goes wrong
164 * @throws IOException if something goes wrong
176165 */
177166 void toIvyFile(File ivyFile) throws ParseException, IOException;
178167
179168 /**
180 * The ModuleDescriptorParser used to parse this module descriptor, null is no parser was used.
181 *
182 * @return
169 * @return the ModuleDescriptorParser used to parse this module descriptor, null is no parser was used.
183170 */
184171 ModuleDescriptorParser getParser();
185172
186173 /**
187 * The resource being the source of this module descriptor, null if no resource corresponds to
188 * this module descriptor
189 *
190 * @return
174 * @return the resource being the source of this module descriptor, null if no resource
175 * corresponds to this module descriptor.
191176 */
192177 Resource getResource();
193178
194179 /**
195 * Returns the Artifact representing this module descriptor itself.
196 * <p>
197180 * Even though the module descriptor is never described as a published artifact of a module in
198181 * the module descriptor itself, it is often useful to consider it as any other artifact of the
199182 * module. This method allows to access to the Artifact object representing this module
200183 * descriptor for this purpose.
201 * </p>
202 *
184 *
203185 * @return the Artifact representing this module descriptor itself.
204186 */
205187 Artifact getMetadataArtifact();
206188
207189 /**
208 * Returns true if this descriptor contains any exclusion rule
209 *
210 * @return true if this descriptor contains any exclusion rule
190 * @return true if this descriptor contains any exclusion rule.
211191 */
212192 boolean canExclude();
213193
214194 /**
215 * Returns true if an exclude rule of this module attached to any of the given configurations
216 * matches the given artifact id, and thus exclude it
217 *
218 * @param moduleConfs
219 * @param artifactId
220 * @return
195 * @param moduleConfs String[]
196 * @param artifactId ditto
197 * @return true if an exclude rule of this module attached to any of the given configurations
198 * matches the given artifact id, and thus exclude it
221199 */
222200 boolean doesExclude(String[] moduleConfs, ArtifactId artifactId);
223201
224202 /**
225 * Returns an array of all the exclude rules this module descriptor currently holds. Module
226 * Descriptor exclude rules are used to exclude (usually transitive) dependencies for the whole
227 * module.
228 *
229 * @return an array of {@link ExcludeRule} this module descriptor holds
230 */
231 public ExcludeRule[] getAllExcludeRules();
232
233 /**
234 * Returns all the dependency descriptor mediators used by this {@link ModuleDescriptor}, as an
235 * instance of {@link ModuleRules}.
236 * <p>
237 * All rules in the {@link ModuleRules} object returned are {@link DependencyDescriptorMediator}
238 * .
239 * </p>
240 *
241 * @return all the dependency descriptor mediators used by this {@link ModuleDescriptor}.
242 */
243 public ModuleRules/* <DependencyDescriptorMediator> */getAllDependencyDescriptorMediators();
244
245 /**
246 * Returns the list of xml namespaces used by extra attributes, as Map from prefix to namespace
247 * URIs.
248 * <p>
249 * The returned list is never <code>null</code>, it is empty when no extra attribute is used or
250 * if extra attributes are used without xml namespaces
251 * </p>
252 *
203 * Module Descriptor exclude rules are used to exclude (usually transitive) dependencies for the
204 * whole module.
205 *
206 * @return an array of all {@link ExcludeRule} this module descriptor currently holds.
207 */
208 ExcludeRule[] getAllExcludeRules();
209
210 /**
211 * @return all the {@link DependencyDescriptorMediator}s used by this
212 * {@link ModuleDescriptor}, as an instance of {@link ModuleRules}.
213 */
214 ModuleRules<DependencyDescriptorMediator> getAllDependencyDescriptorMediators();
215
216 /**
253217 * @return the list of xml namespaces used by extra attributes, as Map from prefix to namespace
254 * URIs.
218 * URIs. The returned list is never null, it is empty when no extra attribute is used or
219 * if extra attributes are used without xml namespaces
255220 */
256221 Map<String, String> getExtraAttributesNamespaces();
257222
258223 /**
259 * Returns the custom info provided in the info tag. All the tags except the description are
260 * given. The key is the name of the tag, the value is its content. <br />
261 *
224 * @return the custom info provided in the info tag. All the tags except the description are
225 * given. The key is the name of the tag, the value is its content.
262226 * @deprecated this method is not returning the full content of the extra info: to get the full
263227 * structure of the extra infos, use getExtraInfos()
264228 */
266230 Map<String, String> getExtraInfo();
267231
268232 /**
269 * Returns a list of extras infos (tag name, attributes and content). All the tags except the
270 * description are given.
271 *
272233 * @since 2.4.0
273 * @return
234 * @return a list of extras infos (tag name, attributes and content). All the tags except the
235 * description are given.
274236 */
275237 List<ExtraInfoHolder> getExtraInfos();
276238
277239 /**
278 * Returns content from first extrainfo matching with given tag name
279 *
280240 * @since 2.4.0
281 * @return
241 * @param tagName String
242 * @return content from first extrainfo matching with given tag name.
282243 */
283244 String getExtraInfoContentByTagName(String tagName);
284245
285246 /**
286 * Returns first extrainfo matching with given tag name
287 *
288247 * @since 2.4.0
289 * @return
248 * @param tagName String
249 * @return first extrainfo matching with given tag name.
290250 */
291251 ExtraInfoHolder getExtraInfoByTagName(String tagName);
292252 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929
3030 /**
3131 * Constructs a new instance.
32 *
32 *
3333 * @param branch
3434 * the branch to give to mediated dependency descriptors, <code>null</code> to keep
3535 * the original branch.
4545 /**
4646 * Returns the version this mediator will give to mediated descriptors, or <code>null</code> if
4747 * this mediator does not override version.
48 *
48 *
4949 * @return the version this mediator will give to mediated descriptors.
5050 */
5151 public String getVersion() {
5555 /**
5656 * Returns the branch this mediator will give to mediated descriptors, or <code>null</code> if
5757 * this mediator does not override branch.
58 *
58 *
5959 * @return the branch this mediator will give to mediated descriptors.
6060 */
6161 public String getBranch() {
6969 return dd;
7070 }
7171
72 String version = this.version == null ? mrid.getRevision() : this.version;
73 String branch = this.branch == null ? mrid.getBranch() : this.branch;
72 String version = (this.version == null) ? mrid.getRevision() : this.version;
73 String branch = (this.branch == null) ? mrid.getBranch() : this.branch;
7474
7575 // if this is a noop, do not construct any new object
7676 if (version.equals(dd.getDependencyRevisionId().getRevision())
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.core.module.descriptor;
18
19 /**
20 * Marker interface for module descriptor of a module in a workspace, then having special semantics,
21 * like artifacts declared by the resolver rather than the descriptor
22 */
23 public interface WorkspaceModuleDescriptor extends ModuleDescriptor {
24
25 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 /**
2020 * Identifies an artifact in a module, without revision information
21 *
21 *
2222 * @see <a href="package-summary.html">org.apache.ivy.core.module.id</a>
2323 */
2424 public class ArtifactId {
3737 * The name of the artifact.
3838 * @param type
3939 * The type of the artifact.
40 * @param ext
41 * The name extension of the artifact.
4042 */
4143 public ArtifactId(ModuleId mid, String name, String type, String ext) {
4244 this.mid = mid;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323
2424 /**
2525 * Identifies an artifact in a particular module revision
26 *
26 *
2727 * @see <a href="package-summary.html">org.apache.ivy.core.module.id</a>
2828 */
2929 public class ArtifactRevisionId extends UnmodifiableExtendableItem {
3333 }
3434
3535 public static ArtifactRevisionId newInstance(ModuleRevisionId mrid, String name, String type,
36 String ext, Map extraAttributes) {
36 String ext, Map<String, String> extraAttributes) {
3737 return new ArtifactRevisionId(new ArtifactId(mrid.getModuleId(), name, type, ext), mrid,
3838 extraAttributes);
3939 }
4646 this(artifactId, mrid, null);
4747 }
4848
49 public ArtifactRevisionId(ArtifactId artfId, ModuleRevisionId mdlRevId, Map extraAttributes) {
49 public ArtifactRevisionId(ArtifactId artfId, ModuleRevisionId mdlRevId,
50 Map<String, String> extraAttributes) {
5051 super(null, extraAttributes);
5152 artifactId = artfId;
5253 mrid = mdlRevId;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.List;
2322 import java.util.Map;
2423
3332 * matcher's attributes. When matcher is looked up against specific module, the key is recreated
3433 * from module's attributes.
3534 * <p>
36 * </p>
3735 * The lookup doesn't target to speed up lookup for non exact pattern matcher. All non exact
3836 * matchers are placed in non-keyed collection.
37 * </p>
3938 * <p>
40 * </p>
4139 * At lookup for matchers against specific module, all non exact pattern matchers are iterated to
4240 * match with module attributes, and exact pattern matchers binding to the same key will also
4341 * iterated to match with module attributes.
42 * </p>
4443 * <p>
45 * </p>
4644 * If there are much more exact pattern matchers than non exact pattern matchers, the matcher lookup
4745 * speed can benefit from this class significantly. A quick example could be user declares lots of
4846 * dependencyOverrides which are typically exact pattern matchers.
47 * </p>
4948 * <p>
50 * </p>
5149 * If there are balanced exact and non exact pattern matchers, the matcher lookup speed doesn't hurt
5250 * by this class.
53 * <p>
5451 * </p>
5552 */
5653 public class MatcherLookup {
5754
58 //private static final String FORMAT = "{org:%s, module:%s}";
55 // private static final String FORMAT = "{org:%s, module:%s}";
5956
6057 private static final String DEFAULT = "{org:" + "default" + ", module:" + "default" + "}";
6158
62 private Map/* <String, List<MapMatcher>> */lookup = new HashMap();
59 private Map<String, List<MapMatcher>> lookup = new HashMap<>();
6360
64 private List/* <MapMatcher> */non_exact_matchers = new ArrayList();
61 private List<MapMatcher> nonExactMatchers = new ArrayList<>();
6562
6663 /**
6764 * Add matcher.
68 *
65 *
6966 * If matcher is exact pattern matcher, it will be associated with a key and placed in keyed
7067 * collection.
71 *
68 *
7269 * If matcher is not exact pattern matcher, it will be placed into non-keyed collection
73 *
74 * @param matcher
70 *
71 * @param matcher MapMatcher
7572 */
7673 public void add(MapMatcher matcher) {
7774 if (!(matcher.getPatternMatcher() instanceof ExactPatternMatcher)) {
78 non_exact_matchers.add(matcher);
75 nonExactMatchers.add(matcher);
7976 return;
8077 }
81 Object key = key(matcher.getAttributes());
82 List exact_matchers = (List) lookup.get(key);
83 if (exact_matchers == null) {
84 exact_matchers = new ArrayList();
85 lookup.put(key, exact_matchers);
78 String key = key(matcher.getAttributes());
79 List<MapMatcher> exactMatchers = lookup.get(key);
80 if (exactMatchers == null) {
81 exactMatchers = new ArrayList<>();
82 lookup.put(key, exactMatchers);
8683 }
87 exact_matchers.add(matcher);
84 exactMatchers.add(matcher);
8885 }
8986
9087 /**
91 * Get a list of matchers which can apply to module with specified attributes
92 *
9388 * @param attrs
9489 * A map of attributes that matcher should match.
95 *
96 * @return list A list of candidate matchers that matches specified attributes
90 *
91 * @return a list of matchers that can apply to module withs specified attributes
9792 */
98 public List get(Map attrs) {
99 List matchers = new ArrayList();
100 // Step 1: find matchers from non_exact_matchers list
101 if (!non_exact_matchers.isEmpty()) {
102 for (Iterator iter = non_exact_matchers.iterator(); iter.hasNext();) {
103 MapMatcher matcher = (MapMatcher) iter.next();
93 public List<MapMatcher> get(Map<String, String> attrs) {
94 List<MapMatcher> matchers = new ArrayList<>();
95 // Step 1: find matchers from nonExactMatchers list
96 if (!nonExactMatchers.isEmpty()) {
97 for (MapMatcher matcher : nonExactMatchers) {
10498 if (matcher.matches(attrs)) {
10599 matchers.add(matcher);
106100 }
107101 }
108102 }
109 // Step 2: find matchers from exact_matchers list of key
110 Object key = key(attrs);
111 List exact_matchers = (List) lookup.get(key);
112 if (exact_matchers != null) {
113 for (Iterator iter = exact_matchers.iterator(); iter.hasNext();) {
114 MapMatcher matcher = (MapMatcher) iter.next();
103 // Step 2: find matchers from exactMatchers list of key
104 String key = key(attrs);
105 List<MapMatcher> exactMatchers = lookup.get(key);
106 if (exactMatchers != null) {
107 for (MapMatcher matcher : exactMatchers) {
115108 if (matcher.matches(attrs)) {
116109 matchers.add(matcher);
117110 }
118111 }
119112 }
120 // Step 3: (iff key != DEFAULT) find matchers from exact_matchers of DEFAULT
121 if (key != DEFAULT) {
122 List default_exact_matchers = (List) lookup.get(DEFAULT);
123 if (default_exact_matchers != null) {
124 for (Iterator iter = default_exact_matchers.iterator(); iter.hasNext();) {
125 MapMatcher matcher = (MapMatcher) iter.next();
113 // Step 3: (iff key != DEFAULT) find matchers from exactMatchers of DEFAULT
114 if (!DEFAULT.equals(key)) {
115 List<MapMatcher> defaultExactMatchers = lookup.get(DEFAULT);
116 if (defaultExactMatchers != null) {
117 for (MapMatcher matcher : defaultExactMatchers) {
126118 if (matcher.matches(attrs)) {
127119 matchers.add(matcher);
128120 }
134126
135127 /**
136128 * Create a key from specified attributes
137 *
129 *
138130 * @param attrs
139131 * A map of attributes
140132 * @return key object
141133 */
142 private Object key(Map attrs) {
143 Object org = attrs.get(IvyPatternHelper.ORGANISATION_KEY);
144 Object module = attrs.get(IvyPatternHelper.MODULE_KEY);
134 private String key(Map<String, String> attrs) {
135 String org = attrs.get(IvyPatternHelper.ORGANISATION_KEY);
136 String module = attrs.get(IvyPatternHelper.MODULE_KEY);
145137 if (org == null || PatternMatcher.ANY_EXPRESSION.equals(org) || module == null
146138 || PatternMatcher.ANY_EXPRESSION.equals(module)) {
147139 return DEFAULT;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727
2828 /**
2929 * Identifies a module, without revision information
30 *
30 *
3131 * @see <a href="package-summary.html">org.apache.ivy.core.module.id</a>
3232 */
33 public class ModuleId implements Comparable {
33 public class ModuleId implements Comparable<ModuleId> {
34
3435 static final String ENCODE_SEPARATOR = ":#@#:";
3536
36 private static final Map/* <ModuleId, WeakReference<ModuleId>> */CACHE = new WeakHashMap();
37 private static final Map<ModuleId, WeakReference<ModuleId>> CACHE = new WeakHashMap<>();
3738
3839 /**
3940 * Returns a ModuleId for the given organization and module name.
40 *
41 *
4142 * @param org
4243 * the module's organization, can be <code>null</code>
4344 * @param name
5556 * This is useful to reduce the number of instances of ModuleId kept in memory, and thus reduce
5657 * memory footprint.
5758 * </p>
58 *
59 *
5960 * @param moduleId
6061 * the module id to return
6162 * @return a unit instance of the given module id.
6465 ModuleId r = null;
6566
6667 synchronized (CACHE) {
67 WeakReference ref = (WeakReference) CACHE.get(moduleId);
68 WeakReference<ModuleId> ref = CACHE.get(moduleId);
6869 if (ref != null) {
69 r = (ModuleId) ref.get();
70 r = ref.get();
7071 }
7172 if (r == null) {
7273 r = moduleId;
73 CACHE.put(r, new WeakReference(r));
74 CACHE.put(r, new WeakReference<>(r));
7475 }
7576 }
7677
8384
8485 private int hash;
8586
86 private Map/* <String, String> */attributes = new HashMap();
87 private Map<String, String> attributes = new HashMap<>();
8788
8889 /**
8990 * Constructor.
90 *
91 *
9192 * @param organisation
9293 * The organisation which creates the module.
9394 * @param name
105106
106107 /**
107108 * Returns the name of the module.
108 *
109 *
109110 * @return The name of the module.
110111 */
111112 public String getName() {
114115
115116 /**
116117 * Returns the name of the organisation.
117 *
118 *
118119 * @return The name of the organisation.
119120 */
120121 public String getOrganisation() {
121122 return organisation;
122123 }
123124
124 /** {@inheritDoc} */
125 @Override
125126 public boolean equals(Object obj) {
126127 if (!(obj instanceof ModuleId)) {
127128 return false;
128129 }
129130 ModuleId other = (ModuleId) obj;
130 if (other.organisation == null) {
131 return organisation == null && other.name.equals(name);
132 } else {
133 return other.organisation.equals(organisation) && other.name.equals(name);
134 }
135 }
136
137 /** {@inheritDoc} */
131 return (other.organisation == null)
132 ? organisation == null && other.name.equals(name)
133 : other.organisation.equals(organisation) && other.name.equals(name);
134 }
135
136 @Override
138137 public int hashCode() {
139138 if (hash == 0) {
140139 // CheckStyle:MagicNumber| OFF
146145 return hash;
147146 }
148147
149 /** {@inheritDoc} */
148 @Override
150149 public String toString() {
151150 return organisation + "#" + name;
152151 }
153152
154 /** {@inheritDoc} */
155 public int compareTo(Object obj) {
156 ModuleId that = (ModuleId) obj;
153 public int compareTo(ModuleId that) {
157154 int result = organisation.compareTo(that.organisation);
158155 if (result == 0) {
159156 result = name.compareTo(that.name);
163160
164161 /**
165162 * Returns the encoded String representing this ModuleId.
166 *
163 *
167164 * @return The ModuleId encoded as String.
168165 */
169166 public String encodeToString() {
173170 /**
174171 * Returns a Map of all attributes of this module id. The Map keys are attribute names as
175172 * Strings, and values are corresponding attribute values (as String too).
176 *
173 *
177174 * @return A Map instance containing all the attributes and their values.
178175 */
179 public Map getAttributes() {
176 public Map<String, String> getAttributes() {
180177 return attributes;
181178 }
182179
183180 /**
184181 * Returns a ModuleId
185 *
186 * @param encoded
182 *
183 * @param encoded String
187184 * @return The new ModuleId.
188185 * @throws IllegalArgumentException
189186 * If the given String could not be decoded.
198195
199196 /**
200197 * Pattern to use to matched mid text representation.
201 *
198 *
202199 * @see #parse(String)
203200 */
204201 public static final Pattern MID_PATTERN = Pattern.compile("("
207204
208205 /**
209206 * Parses the module id text representation and returns it as a {@link ModuleId} instance.
210 *
207 *
211208 * @param mid
212209 * the module id text representation to parse
213210 * @return the ModuleId instance corresponding to the representation
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.lang.ref.WeakReference;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.Map;
2322 import java.util.WeakHashMap;
2423 import java.util.regex.Matcher;
3130
3231 /**
3332 * Identifies a module in a particular version
34 *
33 *
3534 * @see <a href="package-summary.html">org.apache.ivy.core.module.id</a>
3635 */
3736 public class ModuleRevisionId extends UnmodifiableExtendableItem {
37
3838 private static final String ENCODE_SEPARATOR = ModuleId.ENCODE_SEPARATOR;
3939
4040 private static final String ENCODE_PREFIX = "+";
4545
4646 private static final String REV_STRICT_CHARS_PATTERN = "[a-zA-Z0-9\\-/\\._+=,\\[\\]\\{\\}\\(\\):@]";
4747
48 private static final Map/* <ModuleRevisionId, ModuleRevisionId> */CACHE = new WeakHashMap();
48 private static final Map<ModuleRevisionId, WeakReference<ModuleRevisionId>> CACHE = new WeakHashMap<>();
4949
5050 /**
5151 * Pattern to use to matched mrid text representation.
52 *
52 *
5353 * @see #parse(String)
5454 */
5555 public static final Pattern MRID_PATTERN = Pattern.compile("(" + STRICT_CHARS_PATTERN + "*)"
6969 * <p>
7070 * The result is unspecified if the module doesn't respect strict name conventions.
7171 * </p>
72 *
72 *
7373 * @param mrid
7474 * the text representation of the module (as returned by {@link #toString()}). Must
7575 * not be <code>null</code>.
9696 }
9797
9898 public static ModuleRevisionId newInstance(String organisation, String name, String revision,
99 Map extraAttributes) {
99 Map<String, String> extraAttributes) {
100100 return intern(new ModuleRevisionId(ModuleId.newInstance(organisation, name), revision,
101101 extraAttributes));
102102 }
108108 }
109109
110110 public static ModuleRevisionId newInstance(String organisation, String name, String branch,
111 String revision, Map extraAttributes) {
111 String revision, Map<String, String> extraAttributes) {
112112 return intern(new ModuleRevisionId(ModuleId.newInstance(organisation, name), branch,
113113 revision, extraAttributes));
114114 }
115115
116116 public static ModuleRevisionId newInstance(String organisation, String name, String branch,
117 String revision, Map extraAttributes, boolean replaceNullBranchWithDefault) {
117 String revision, Map<String, String> extraAttributes,
118 boolean replaceNullBranchWithDefault) {
118119 return intern(new ModuleRevisionId(ModuleId.newInstance(organisation, name), branch,
119120 revision, extraAttributes, replaceNullBranchWithDefault));
120121 }
139140 * <p>
140141 * When using static newInstances methods, this method is already called.
141142 * </p>
142 *
143 *
143144 * @param moduleRevisionId
144145 * the module revision id to intern
145146 * @return an interned ModuleRevisionId
148149 ModuleRevisionId r = null;
149150
150151 synchronized (CACHE) {
151 WeakReference ref = (WeakReference) CACHE.get(moduleRevisionId);
152 WeakReference<ModuleRevisionId> ref = CACHE.get(moduleRevisionId);
152153 if (ref != null) {
153 r = (ModuleRevisionId) ref.get();
154 r = ref.get();
154155 }
155156 if (r == null) {
156157 r = moduleRevisionId;
157 CACHE.put(r, new WeakReference(r));
158 CACHE.put(r, new WeakReference<>(r));
158159 }
159160 }
160161
179180 this(moduleId, branch, revision, null);
180181 }
181182
182 private ModuleRevisionId(ModuleId moduleId, String revision, Map extraAttributes) {
183 private ModuleRevisionId(ModuleId moduleId, String revision, Map<String, String> extraAttributes) {
183184 this(moduleId, null, revision, extraAttributes);
184185 }
185186
186 private ModuleRevisionId(ModuleId moduleId, String branch, String revision, Map extraAttributes) {
187 private ModuleRevisionId(ModuleId moduleId, String branch, String revision,
188 Map<String, String> extraAttributes) {
187189 this(moduleId, branch, revision, extraAttributes, true);
188190 }
189191
190192 private ModuleRevisionId(ModuleId moduleId, String branch, String revision,
191 Map extraAttributes, boolean replaceNullBranchWithDefault) {
193 Map<String, String> extraAttributes, boolean replaceNullBranchWithDefault) {
192194 super(null, extraAttributes);
193195 this.moduleId = moduleId;
194196 IvyContext context = IvyContext.getContext();
220222 return revision;
221223 }
222224
225 @Override
223226 public boolean equals(Object obj) {
224227 if (!(obj instanceof ModuleRevisionId)) {
225228 return false;
226229 }
227230 ModuleRevisionId other = (ModuleRevisionId) obj;
228231
229 if (!other.getRevision().equals(getRevision())) {
230 return false;
231 } else if (other.getBranch() == null && getBranch() != null) {
232 return false;
233 } else if (other.getBranch() != null && !other.getBranch().equals(getBranch())) {
234 return false;
235 } else if (!other.getModuleId().equals(getModuleId())) {
236 return false;
237 } else {
238 return other.getQualifiedExtraAttributes().equals(getQualifiedExtraAttributes());
239 }
240 }
241
232 return other.getRevision().equals(getRevision())
233 && !(other.getBranch() == null && getBranch() != null)
234 && !(other.getBranch() != null && !other.getBranch().equals(getBranch()))
235 && other.getModuleId().equals(getModuleId())
236 && other.getQualifiedExtraAttributes().equals(getQualifiedExtraAttributes());
237 }
238
239 @Override
242240 public int hashCode() {
243241 if (hash == 0) {
244242 // CheckStyle:MagicNumber| OFF
252250 return hash;
253251 }
254252
253 @Override
255254 public String toString() {
256255 return moduleId + (branch == null || branch.length() == 0 ? "" : "#" + branch) + ";"
257256 + (revision == null ? "NONE" : revision);
258257 }
259258
260259 public String encodeToString() {
261 StringBuffer buf = new StringBuffer();
262 Map attributes = new HashMap(getAttributes());
260 StringBuilder buf = new StringBuilder();
261 Map<String, String> attributes = new HashMap<>(getAttributes());
263262 attributes.keySet().removeAll(getExtraAttributes().keySet());
264263 attributes.putAll(getQualifiedExtraAttributes());
265264
266 for (Iterator iter = attributes.keySet().iterator(); iter.hasNext();) {
267 String attName = (String) iter.next();
268 String value = (String) attributes.get(attName);
269 value = value == null ? NULL_ENCODE : value;
270 buf.append(ENCODE_PREFIX).append(attName).append(ENCODE_SEPARATOR)
265 for (Map.Entry<String, String> att : attributes.entrySet()) {
266 String value = att.getValue();
267 value = (value == null) ? NULL_ENCODE : value;
268 buf.append(ENCODE_PREFIX).append(att.getKey()).append(ENCODE_SEPARATOR)
271269 .append(ENCODE_PREFIX).append(value).append(ENCODE_SEPARATOR);
272270 }
273271 return buf.toString();
279277 throw new IllegalArgumentException("badly encoded module revision id: '" + encoded
280278 + "'");
281279 }
282 Map attributes = new HashMap();
280 Map<String, String> attributes = new HashMap<>();
283281 for (int i = 0; i < parts.length; i += 2) {
284282 String attName = parts[i];
285283 if (!attName.startsWith(ENCODE_PREFIX)) {
300298 }
301299 attributes.put(attName, attValue);
302300 }
303 String org = (String) attributes.remove(IvyPatternHelper.ORGANISATION_KEY);
304 String mod = (String) attributes.remove(IvyPatternHelper.MODULE_KEY);
305 String rev = (String) attributes.remove(IvyPatternHelper.REVISION_KEY);
306 String branch = (String) attributes.remove(IvyPatternHelper.BRANCH_KEY);
301 String org = attributes.remove(IvyPatternHelper.ORGANISATION_KEY);
302 String mod = attributes.remove(IvyPatternHelper.MODULE_KEY);
303 String rev = attributes.remove(IvyPatternHelper.REVISION_KEY);
304 String branch = attributes.remove(IvyPatternHelper.BRANCH_KEY);
307305 if (org == null) {
308306 throw new IllegalArgumentException("badly encoded module revision id: '" + encoded
309307 + "': no organisation");
330328 private static String normalizeRevision(String revision) {
331329 if (revision.startsWith("[") && revision.endsWith("]") && revision.indexOf(',') == -1) {
332330 if (IvyPatternHelper.getTokenString(IvyPatternHelper.REVISION_KEY).equals(revision)) {
333 // this is the case when listing dynamic revions
331 // this is the case when listing dynamic revisions
334332 return revision;
335333 }
336334
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.Collections;
21 import java.util.Iterator;
2221 import java.util.LinkedHashMap;
2322 import java.util.List;
2423 import java.util.Map;
4746 * Rules themselves can be represented by any object, depending on the purpose of the rule (define
4847 * which resolver to use, which TTL in cache, ...)
4948 * </p>
49 *
50 * @param <T> a type parameter
5051 */
51 public class ModuleRules {
52 private Map/* <MapMatcher,Object> */rules = new LinkedHashMap();
53
54 private MatcherLookup matcher_lookup = new MatcherLookup();
52 public class ModuleRules<T> {
53
54 private Map<MapMatcher, T> rules = new LinkedHashMap<>();
55
56 private MatcherLookup matcherLookup = new MatcherLookup();
5557
5658 /**
5759 * Constructs an empty ModuleRules.
5961 public ModuleRules() {
6062 }
6163
62 private ModuleRules(Map/* <MapMatcher,Object> */rules) {
63 this.rules = new LinkedHashMap(rules);
64 for (Iterator iter = rules.keySet().iterator(); iter.hasNext();) {
65 matcher_lookup.add((MapMatcher) iter.next());
64 private ModuleRules(Map<MapMatcher, T> rules) {
65 this.rules = new LinkedHashMap<>(rules);
66 for (MapMatcher matcher : rules.keySet()) {
67 matcherLookup.add(matcher);
6668 }
6769 }
6870
6971 /**
7072 * Defines a new rule for the given condition.
71 *
73 *
7274 * @param condition
7375 * the condition for which the rule should be applied. Must not be <code>null</code>.
7476 * @param rule
7577 * the rule to apply. Must not be <code>null</code>.
7678 */
77 public void defineRule(MapMatcher condition, Object rule) {
79 public void defineRule(MapMatcher condition, T rule) {
7880 Checks.checkNotNull(condition, "condition");
7981 Checks.checkNotNull(rule, "rule");
8082
8183 rules.put(condition, rule);
82 matcher_lookup.add(condition);
84 matcherLookup.add(condition);
8385 }
8486
8587 /**
8688 * Returns the rule object matching the given {@link ModuleId}, or <code>null</code> if no rule
8789 * applies.
88 *
90 *
8991 * @param mid
9092 * the {@link ModuleId} to search the rule for. Must not be <code>null</code>.
9193 * @return the rule object matching the given {@link ModuleId}, or <code>null</code> if no rule
9294 * applies.
9395 * @see #getRule(ModuleId, Filter)
9496 */
95 public Object getRule(ModuleId mid) {
96 return getRule(mid, NoFilter.INSTANCE);
97 public T getRule(ModuleId mid) {
98 return getRule(mid, NoFilter.<T> instance());
9799 }
98100
99101 /**
100102 * Returns the rules objects matching the given {@link ModuleId}, or an empty array if no rule
101103 * applies.
102 *
104 *
103105 * @param mid
104106 * the {@link ModuleId} to search the rule for. Must not be <code>null</code>.
105107 * @return an array of rule objects matching the given {@link ModuleId}.
106108 */
107 public Object[] getRules(ModuleId mid) {
108 return getRules(mid.getAttributes(), NoFilter.INSTANCE);
109 public List<T> getRules(ModuleId mid) {
110 return getRules(mid.getAttributes(), NoFilter.<T> instance());
109111 }
110112
111113 /**
112114 * Returns the rule object matching the given {@link ModuleRevisionId}, or <code>null</code> if
113115 * no rule applies.
114 *
116 *
115117 * @param mrid
116118 * the {@link ModuleRevisionId} to search the rule for. Must not be <code>null</code>
117119 * .
119121 * no rule applies.
120122 * @see #getRule(ModuleRevisionId, Filter)
121123 */
122 public Object getRule(ModuleRevisionId mrid) {
123 return getRule(mrid, NoFilter.INSTANCE);
124 public T getRule(ModuleRevisionId mrid) {
125 return getRule(mrid, NoFilter.<T> instance());
124126 }
125127
126128 /**
127129 * Returns the rule object matching the given {@link ModuleId} and accepted by the given
128130 * {@link Filter}, or <code>null</code> if no rule applies.
129 *
131 *
130132 * @param mid
131133 * the {@link ModuleRevisionId} to search the rule for. Must not be <code>null</code>
132134 * .
139141 * applies.
140142 * @see #getRule(ModuleRevisionId, Filter)
141143 */
142 public Object getRule(ModuleId mid, Filter filter) {
144 public T getRule(ModuleId mid, Filter<T> filter) {
143145 Checks.checkNotNull(mid, "mid");
144146 return getRule(mid.getAttributes(), filter);
145147 }
147149 /**
148150 * Returns the rule object matching the given {@link ModuleRevisionId} and accepted by the given
149151 * {@link Filter}, or <code>null</code> if no rule applies.
150 *
152 *
151153 * @param mrid
152154 * the {@link ModuleRevisionId} to search the rule for. Must not be <code>null</code>
153155 * .
160162 * no rule applies.
161163 * @see #getRule(ModuleRevisionId)
162164 */
163 public Object getRule(ModuleRevisionId mrid, Filter filter) {
165 public T getRule(ModuleRevisionId mrid, Filter<T> filter) {
164166 Checks.checkNotNull(mrid, "mrid");
165167 Checks.checkNotNull(filter, "filter");
166 Map moduleAttributes = mrid.getAttributes();
168 Map<String, String> moduleAttributes = mrid.getAttributes();
167169 return getRule(moduleAttributes, filter);
168170 }
169171
170 private Object getRule(Map moduleAttributes, Filter filter) {
171 List matchers = matcher_lookup.get(moduleAttributes);
172 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
173 MapMatcher midm = (MapMatcher) iter.next();
174 Object rule = rules.get(midm);
172 private T getRule(Map<String, String> moduleAttributes, Filter<T> filter) {
173 for (MapMatcher midm : matcherLookup.get(moduleAttributes)) {
174 T rule = rules.get(midm);
175175 if (filter.accept(rule)) {
176176 return rule;
177177 }
182182 /**
183183 * Returns the rules object matching the given {@link ModuleRevisionId} and accepted by the
184184 * given {@link Filter}, or an empty array if no rule applies.
185 *
185 *
186186 * @param mrid
187187 * the {@link ModuleRevisionId} to search the rule for. Must not be <code>null</code>
188188 * .
192192 * {@link ModuleRevisionId}. Must not be <code>null</code>.
193193 * @return an array of rule objects matching the given {@link ModuleRevisionId}.
194194 */
195 public Object[] getRules(ModuleRevisionId mrid, Filter filter) {
195 public List<T> getRules(ModuleRevisionId mrid, Filter<T> filter) {
196196 Checks.checkNotNull(mrid, "mrid");
197197 Checks.checkNotNull(filter, "filter");
198 Map moduleAttributes = mrid.getAttributes();
198 Map<String, String> moduleAttributes = mrid.getAttributes();
199199 return getRules(moduleAttributes, filter);
200200 }
201201
202 private Object[] getRules(Map moduleAttributes, Filter filter) {
203 List matchers = matcher_lookup.get(moduleAttributes);
204 List matchingRules = new ArrayList();
205 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
206 MapMatcher midm = (MapMatcher) iter.next();
207 Object rule = rules.get(midm);
202 private List<T> getRules(Map<String, String> moduleAttributes, Filter<T> filter) {
203 List<T> matchingRules = new ArrayList<>();
204 for (MapMatcher midm : matcherLookup.get(moduleAttributes)) {
205 T rule = rules.get(midm);
208206 if (filter.accept(rule)) {
209207 matchingRules.add(rule);
210208 }
211209 }
212 return matchingRules.toArray();
210 return matchingRules;
213211 }
214212
215213 /**
216214 * Dump the list of rules to {@link Message#debug(String)}
217 *
215 *
218216 * @param prefix
219217 * the prefix to use for each line dumped
220218 */
221219 public void dump(String prefix) {
222220 if (rules.isEmpty()) {
223221 Message.debug(prefix + "NONE");
224 } else {
225 for (Iterator iter = rules.keySet().iterator(); iter.hasNext();) {
226 MapMatcher midm = (MapMatcher) iter.next();
227 Object rule = rules.get(midm);
228 Message.debug(prefix + midm + " -> " + rule);
229 }
222 return;
223 }
224 for (Map.Entry<MapMatcher, T> entry : rules.entrySet()) {
225 MapMatcher midm = entry.getKey();
226 T rule = entry.getValue();
227 Message.debug(prefix + midm + " -> " + rule);
230228 }
231229 }
232230
236234 * The rules are returned in a Map where they keys are the MapMatchers matching the rules
237235 * object, and the values are the rules object themselves.
238236 * </p>
239 *
237 *
240238 * @return an unmodifiable view of all the rules defined on this ModuleRules.
241239 */
242 public Map/* <MapMatcher,Object> */getAllRules() {
240 public Map<MapMatcher, T> getAllRules() {
243241 return Collections.unmodifiableMap(rules);
244242 }
245243
246 public Object clone() {
247 return new ModuleRules(rules);
244 public ModuleRules<T> clone() {
245 return new ModuleRules<>(rules);
248246 }
249247 }
0 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
10 <!--
21 Licensed to the Apache Software Foundation (ASF) under one
32 or more contributor license agreements. See the NOTICE file
76 "License"); you may not use this file except in compliance
87 with the License. You may obtain a copy of the License at
98
10 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1110
1211 Unless required by applicable law or agreed to in writing,
1312 software distributed under the License is distributed on an
1413 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1514 KIND, either express or implied. See the License for the
1615 specific language governing permissions and limitations
17 under the License.
16 under the License.
1817 -->
1918 <html>
2019 <head>
2726 As identifiers, they do not store any information on the module content and detailed metadata (like dependencies).
2827 </p>
2928 <h2>Classes</h2>
30 <p>
31 <ul>
32 <li>ModuleId</li> is used as the identifier of module, without considering its version. It's basically an organization and module name couple.
33 <li>ModuleRevisionId</li> is used as the identifier of a module in a particular version or version constraint. It is composed of a ModuleId, a revision, and optionally a branch and extra attributes.
34 <li>ArtifactId</li> identifies an artifact without considering its version. It's basically a ModuleId and an artifact name, type and extension, plus optional extra attributes.
35 <li>ArtifactRevisionId</li> identifies an artifact of a module in a particular version. It is composed of a ModuleRevisionId along with artifact identifier like the name type and extension.
36 </ul>
37 </p>
29 <dl>
30 <dt>ModuleId</dt><dd>is used as the identifier of module, without considering its version. It's basically an organization and module name couple.</dd>
31 <dt>ModuleRevisionId</dt><dd>is used as the identifier of a module in a particular version or version constraint. It is composed of a ModuleId, a revision, and optionally a branch and extra attributes.</dd>
32 <dt>ArtifactId</dt><dd>identifies an artifact without considering its version. It's basically a ModuleId and an artifact name, type and extension, plus optional extra attributes.</dd>
33 <dt>ArtifactRevisionId</dt><dd>identifies an artifact of a module in a particular version. It is composed of a ModuleRevisionId along with artifact identifier like the name type and extension.</dd>
34 </dl>
3835 <h2>Text Representation</h2>
3936 <p>
4037 These classes share an homogeneous text representation, which can be easily obtained through the toString() method.
4542 The type and surrounding parenthesis are present only if different from the extension.
4643 </p>
4744 <p>
48 A textual representation can be parsed into an object (supported for ModuleRevisionId only yet), as long as a strict set of characters is used for each field (which is recommended).<br/>
45 A textual representation can be parsed into an object (supported for ModuleRevisionId only yet), as long as a strict set of characters is used for each field (which is recommended).
46 </p>
4947 Allowed characters are:
50 <ul>
51 <li>organisation</li> a-z A-Z 0-9 - / . _ + =
52 <li>module</li> a-z A-Z 0-9 - / . _ + =
53 <li>branch</li> a-z A-Z 0-9 - / . _ + =
54 <li>revision</li> a-z A-Z 0-9 - / . _ + = , [ ] { } ( ) : @
55 <li>artifact</li> a-z A-Z 0-9 - / . _ + =
56 <li>extension</li> a-z A-Z 0-9 - / . _ + =
57 <li>type</li> a-z A-Z 0-9 - / . _ + =
58 </ul>
48 <dl>
49 <dt>organisation</dt><dd><code>a-z A-Z 0-9 - / . _ + =</code></dd>
50 <dt>module</dt><dd><code>a-z A-Z 0-9 - / . _ + =</code></dd>
51 <dt>branch</dt><dd><code>a-z A-Z 0-9 - / . _ + =</code></dd>
52 <dt>revision</dt><dd><code>a-z A-Z 0-9 - / . _ + = , [ ] { } ( ) : @</code></dd>
53 <dt>artifact</dt><dd><code>a-z A-Z 0-9 - / . _ + =</code></dd>
54 <dt>extension</dt><dd><code>a-z A-Z 0-9 - / . _ + =</code></dd>
55 <dt>type</dt><dd><code>a-z A-Z 0-9 - / . _ + =</code></dd>
56 </dl>
5957
60 </body>
58 </body>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.ArrayList;
2020 import java.util.Arrays;
2121 import java.util.HashMap;
22 import java.util.Iterator;
2322 import java.util.List;
24 import java.util.ListIterator;
2523 import java.util.Map;
2624
2725 import org.apache.ivy.core.IvyContext;
4139 return IvyContext.getContext().getSettings().getStatusManager();
4240 }
4341
44 private List status = new ArrayList();
42 private final List<Status> statuses = new ArrayList<>();
4543
4644 private String defaultStatus;
4745
4846 // for easier querying only
49 private Map statusPriorityMap;
47 private Map<String, Integer> statusPriorityMap;
5048
51 private Map statusIntegrationMap;
49 private Map<String, Boolean> statusIntegrationMap;
5250
5351 private String deliveryStatusListString;
5452
5553 public StatusManager(Status[] status, String defaultStatus) {
56 this.status.addAll(Arrays.asList(status));
54 this.statuses.addAll(Arrays.asList(status));
5755 this.defaultStatus = defaultStatus;
5856
5957 computeMaps();
6361 }
6462
6563 public void addStatus(Status status) {
66 this.status.add(status);
64 this.statuses.add(status);
6765 }
6866
6967 public void setDefaultStatus(String defaultStatus) {
7068 this.defaultStatus = defaultStatus;
7169 }
7270
73 public List getStatuses() {
74 return status;
71 public List<Status> getStatuses() {
72 return statuses;
7573 }
7674
7775 private void computeMaps() {
78 if (status.isEmpty()) {
79 throw new IllegalStateException("badly configured statuses: no status found");
76 if (statuses.isEmpty()) {
77 throw new IllegalStateException("badly configured statuses: none found");
8078 }
81 statusPriorityMap = new HashMap();
82 for (ListIterator iter = status.listIterator(); iter.hasNext();) {
83 Status status = (Status) iter.next();
84 statusPriorityMap.put(status.getName(), new Integer(iter.previousIndex()));
79 statusPriorityMap = new HashMap<>();
80 for (Status status : statuses) {
81 statusPriorityMap.put(status.getName(), statuses.indexOf(status));
8582 }
86 statusIntegrationMap = new HashMap();
87 for (Iterator iter = status.iterator(); iter.hasNext();) {
88 Status status = (Status) iter.next();
89 statusIntegrationMap.put(status.getName(), Boolean.valueOf(status.isIntegration()));
83 statusIntegrationMap = new HashMap<>();
84 for (Status status : statuses) {
85 statusIntegrationMap.put(status.getName(), status.isIntegration());
9086 }
9187 }
9288
10197 if (statusPriorityMap == null) {
10298 computeMaps();
10399 }
104 Integer priority = (Integer) statusPriorityMap.get(status);
100 Integer priority = statusPriorityMap.get(status);
105101 if (priority == null) {
106102 Message.debug("unknown status " + status + ": assuming lowest priority");
107103 return Integer.MAX_VALUE;
108104 }
109 return priority.intValue();
105 return priority;
110106 }
111107
112108 public boolean isIntegration(String status) {
113109 if (statusIntegrationMap == null) {
114110 computeMaps();
115111 }
116 Boolean isIntegration = (Boolean) statusIntegrationMap.get(status);
112 Boolean isIntegration = statusIntegrationMap.get(status);
117113 if (isIntegration == null) {
118114 Message.debug("unknown status " + status + ": assuming integration");
119115 return true;
120116 }
121 return isIntegration.booleanValue();
117 return isIntegration;
122118 }
123119
124120 public String getDeliveryStatusListString() {
125121 if (deliveryStatusListString == null) {
126 StringBuffer ret = new StringBuffer();
127 for (Iterator iter = status.iterator(); iter.hasNext();) {
128 Status status = (Status) iter.next();
122 StringBuilder ret = new StringBuilder();
123 for (Status status : statuses) {
129124 if (!status.isIntegration()) {
130125 ret.append(status.getName()).append(",");
131126 }
140135
141136 public String getDefaultStatus() {
142137 if (defaultStatus == null) {
143 if (status.isEmpty()) {
144 throw new IllegalStateException("badly configured statuses: no status found");
138 if (statuses.isEmpty()) {
139 throw new IllegalStateException("badly configured statuses: none found");
145140 }
146 defaultStatus = ((Status) status.get(status.size() - 1)).getName();
141 defaultStatus = statuses.get(statuses.size() - 1).getName();
147142 }
148143 return defaultStatus;
149144 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.core.pack;
1818
1919 import java.io.File;
20 import java.io.FileNotFoundException;
2120 import java.io.IOException;
2221 import java.io.InputStream;
2322
3635 }
3736
3837 @Override
39 protected void writeFile(InputStream zip, File f) throws FileNotFoundException, IOException {
38 protected void writeFile(InputStream zip, File f) throws IOException {
4039 // XXX maybe we should only unpack file listed by the 'Bundle-ClassPath' MANIFEST header ?
4140 if (f.getName().endsWith(".jar.pack.gz")) {
4241 zip = FileUtil.unwrapPack200(zip);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5454 throw new IllegalStateException("Unsupported archive only packing type '"
5555 + packings[i] + "' in the streamed chain: " + packaging);
5656 }
57 ext = ((StreamPacking) packing).getUnpackedExtension(ext);
57 ext = packing.getUnpackedExtension(ext);
5858 }
5959 ArchivePacking packing = settings.getPackingRegistry().get(packings[0]);
6060 if (packing == null) {
6363 }
6464 ext = packing.getUnpackedExtension(ext);
6565
66 DefaultArtifact unpacked = new DefaultArtifact(artifact.getModuleRevisionId(),
66 return new DefaultArtifact(artifact.getModuleRevisionId(),
6767 artifact.getPublicationDate(), artifact.getName(),
6868 artifact.getType() + "_unpacked", ext);
69
70 return unpacked;
7169 }
7270
73 public void unpackArtifact(Artifact artifact, File localFile, File archiveFile)
71 public Artifact unpackArtifact(Artifact artifact, File localFile, File archiveFile)
7472 throws IOException {
7573 String packaging = artifact.getExtraAttribute("packaging");
7674 if (packaging == null) {
7775 // not declared as packed, nothing to do
78 return;
76 return null;
7977 }
80
78 String ext = artifact.getExt();
8179 String[] packings = packaging.split(",");
8280 InputStream in = null;
8381 try {
9391 + packings[i] + "' in the streamed chain: " + packaging);
9492 }
9593 in = ((StreamPacking) packing).unpack(in);
94 ext = packing.getUnpackedExtension(ext);
9695 }
9796 ArchivePacking packing = settings.getPackingRegistry().get(packings[0]);
9897 if (packing == null) {
10099 + "' in the packing chain: " + packaging);
101100 }
102101 packing.unpack(in, archiveFile);
102 ext = packing.getUnpackedExtension(ext);
103103 } finally {
104104 if (in != null) {
105105 try {
109109 }
110110 }
111111 }
112
113 return new DefaultArtifact(artifact.getModuleRevisionId(),
114 artifact.getPublicationDate(), artifact.getName(),
115 artifact.getType() + "_unpacked", ext);
116
112117 }
113118
114119 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 public class PackingRegistry {
2323
24 private Map<String, ArchivePacking> packings = new HashMap<String, ArchivePacking>();
24 private Map<String, ArchivePacking> packings = new HashMap<>();
2525
2626 public PackingRegistry() {
2727 // register defaults
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.core.pack;
1818
1919 import java.io.File;
20 import java.io.FileNotFoundException;
2120 import java.io.FileOutputStream;
2221 import java.io.IOException;
2322 import java.io.InputStream;
4948
5049 @Override
5150 public void unpack(InputStream packed, File dest) throws IOException {
52 ZipInputStream zip = null;
53 try {
54 zip = new ZipInputStream(packed);
51 try (ZipInputStream zip = new ZipInputStream(packed)) {
5552 ZipEntry entry = null;
5653 while (((entry = zip.getNextEntry()) != null)) {
5754 File f = new File(dest, entry.getName());
7168
7269 f.setLastModified(entry.getTime());
7370 }
74 } finally {
75 if (zip != null) {
76 try {
77 zip.close();
78 } catch (IOException e) {
79 // ignore
80 }
81 }
8271 }
8372 }
8473
85 protected void writeFile(InputStream zip, File f) throws FileNotFoundException, IOException {
86 FileOutputStream out = new FileOutputStream(f);
87 try {
74 protected void writeFile(InputStream zip, File f) throws IOException {
75 try (FileOutputStream out = new FileOutputStream(f)) {
8876 FileUtil.copy(zip, out, null, false);
89 } finally {
90 try {
91 out.close();
92 } catch (IOException e) {
93 // ignore
94 }
9577 }
9678 }
9779
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 import java.util.Collection;
2626 import java.util.Date;
2727 import java.util.HashSet;
28 import java.util.Iterator;
2928 import java.util.LinkedHashMap;
3029 import java.util.LinkedHashSet;
3130 import java.util.Map;
32 import java.util.Map.Entry;
3331 import java.util.Set;
3432
3533 import org.apache.ivy.core.IvyContext;
4745 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
4846 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorUpdater;
4947 import org.apache.ivy.plugins.resolver.DependencyResolver;
50 import org.apache.ivy.util.ConfigurationUtils;
5148 import org.apache.ivy.util.Message;
5249 import org.xml.sax.SAXException;
50
51 import static org.apache.ivy.util.ConfigurationUtils.replaceWildcards;
5352
5453 public class PublishEngine {
5554 private PublishEngineSettings settings;
7372 * reports. The extra artifacts array can be null (= no extra artifacts), and if non null only
7473 * the name, type, ext url and extra attributes of the artifacts are really used. Other methods
7574 * can return null safely.
75 *
76 * @param mrid ModuleRevisionId
77 * @param srcArtifactPattern a Collection of String
78 * @param resolverName String
79 * @param options PublishOptions
80 * @return Collection&lt;Artifact&gt;
81 * @throws IOException if something goes wrong
7682 */
77 public Collection publish(ModuleRevisionId mrid, Collection srcArtifactPattern,
78 String resolverName, PublishOptions options) throws IOException {
83 public Collection<Artifact> publish(ModuleRevisionId mrid,
84 Collection<String> srcArtifactPattern, String resolverName, PublishOptions options)
85 throws IOException {
7986 Message.info(":: publishing :: " + mrid.getModuleId());
8087 Message.verbose("\tvalidate = " + options.isValidate());
8188 long start = System.currentTimeMillis();
109116 File tmp = File.createTempFile("ivy", ".xml");
110117 tmp.deleteOnExit();
111118
112 String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md);
113 Set confsToRemove = new HashSet(Arrays.asList(md.getConfigurationsNames()));
119 String[] confs = replaceWildcards(options.getConfs(), md);
120 Set<String> confsToRemove = new HashSet<>(Arrays.asList(md
121 .getConfigurationsNames()));
114122 confsToRemove.removeAll(Arrays.asList(confs));
115123
116124 try {
119127 tmp,
120128 new UpdateOptions()
121129 .setSettings(settings)
122 .setStatus(
123 options.getStatus() == null ? md.getStatus() : options
124 .getStatus())
130 .setStatus(options.getStatus() == null ? md.getStatus()
131 : options.getStatus())
125132 .setRevision(options.getPubrevision())
126133 .setBranch(options.getPubBranch())
127 .setPubdate(
128 options.getPubdate() == null ? new Date() : options
129 .getPubdate())
134 .setPubdate(options.getPubdate() == null ? new Date()
135 : options.getPubdate())
130136 .setMerge(options.isMerge())
131137 .setMergedDescriptor(md)
132138 .setConfsToExclude(
133 (String[]) confsToRemove.toArray(new String[confsToRemove
134 .size()])));
139 confsToRemove.toArray(new String[confsToRemove.size()])));
135140 ivyFile = tmp;
136141 // we parse the new file to get updated module descriptor
137142 md = XmlModuleDescriptorParser.getInstance().parseDescriptor(settings,
168173 }
169174
170175 // collect all declared artifacts of this module
171 Collection missing = publish(md, srcArtifactPattern, resolver, options);
176 Collection<Artifact> missing = publish(md, srcArtifactPattern, resolver, options);
172177 Message.verbose("\tpublish done (" + (System.currentTimeMillis() - start) + "ms)");
173178 return missing;
174179 }
175180
176 public Collection publish(ModuleDescriptor md, Collection srcArtifactPattern,
181 public Collection<Artifact> publish(ModuleDescriptor md, Collection<String> srcArtifactPattern,
177182 DependencyResolver resolver, PublishOptions options) throws IOException {
178 Collection missing = new ArrayList();
179 Set artifactsSet = new LinkedHashSet();
180 String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md);
181
182 for (int i = 0; i < confs.length; i++) {
183 Artifact[] artifacts = md.getArtifacts(confs[i]);
184 for (int j = 0; j < artifacts.length; j++) {
185 artifactsSet.add(artifacts[j]);
186 }
183 Collection<Artifact> missing = new ArrayList<>();
184 Set<Artifact> artifactsSet = new LinkedHashSet<>();
185
186 for (String conf : replaceWildcards(options.getConfs(), md)) {
187 artifactsSet.addAll(Arrays.asList(md.getArtifacts(conf)));
187188 }
188189 Artifact[] extraArtifacts = options.getExtraArtifacts();
189190 if (extraArtifacts != null) {
190 for (int i = 0; i < extraArtifacts.length; i++) {
191 artifactsSet.add(new MDArtifact(md, extraArtifacts[i].getName(), extraArtifacts[i]
192 .getType(), extraArtifacts[i].getExt(), extraArtifacts[i].getUrl(),
193 extraArtifacts[i].getQualifiedExtraAttributes()));
191 for (Artifact extraArtifact : extraArtifacts) {
192 artifactsSet.add(new MDArtifact(md, extraArtifact.getName(), extraArtifact
193 .getType(), extraArtifact.getExt(), extraArtifact.getUrl(),
194 extraArtifact.getQualifiedExtraAttributes()));
194195 }
195196 }
196197 // now collects artifacts files
197 Map/* <Artifact,File> */artifactsFiles = new LinkedHashMap();
198 for (Iterator iter = artifactsSet.iterator(); iter.hasNext();) {
199 Artifact artifact = (Artifact) iter.next();
200 for (Iterator iterator = srcArtifactPattern.iterator(); iterator.hasNext();) {
201 String pattern = (String) iterator.next();
198 Map<Artifact, File> artifactsFiles = new LinkedHashMap<>();
199 for (Artifact artifact : artifactsSet) {
200 for (String pattern : srcArtifactPattern) {
202201 File artifactFile = settings.resolveFile(IvyPatternHelper.substitute(
203202 settings.substitute(pattern), artifact));
204203 if (artifactFile.exists()) {
207206 }
208207 }
209208 if (!artifactsFiles.containsKey(artifact)) {
210 StringBuffer sb = new StringBuffer();
211 sb.append("missing artifact " + artifact + ":\n");
212 for (Iterator iterator = srcArtifactPattern.iterator(); iterator.hasNext();) {
213 String pattern = (String) iterator.next();
214 sb.append("\t"
215 + settings.resolveFile(IvyPatternHelper.substitute(pattern, artifact))
216 + " file does not exist\n");
209 StringBuilder sb = new StringBuilder();
210 sb.append("missing artifact ").append(artifact).append(":\n");
211 for (String pattern : srcArtifactPattern) {
212 sb.append("\t").append(settings.resolveFile(IvyPatternHelper.substitute(pattern,
213 artifact))).append(" file does not exist\n");
217214 }
218215 if (options.isWarnOnMissing() || options.isHaltOnMissing()) {
219216 Message.warn(sb.toString());
252249 try {
253250 resolver.beginPublishTransaction(md.getModuleRevisionId(), options.isOverwrite());
254251 // for each declared published artifact in this descriptor, do:
255 for (Iterator iter = artifactsFiles.entrySet().iterator(); iter.hasNext();) {
256 Map.Entry entry = (Entry) iter.next();
257 Artifact artifact = (Artifact) entry.getKey();
258 File artifactFile = (File) entry.getValue();
259 publish(artifact, artifactFile, resolver, options.isOverwrite());
252 for (Map.Entry<Artifact, File> entry : artifactsFiles.entrySet()) {
253 publish(entry.getKey(), entry.getValue(), resolver, options.isOverwrite());
260254 }
261255 resolver.commitPublishTransaction();
262256 successfullyPublished = true;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232 * artifacts array can be null (= no extra artifacts), and if non null only the name, type, ext url
3333 * and extra attributes of the artifacts are really used. Other methods (on the artifacts) can
3434 * return null safely.
35 *
35 *
3636 * @see PublishEngine
3737 */
3838 public class PublishOptions {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5656
5757 private File unpackedLocalFile;
5858
59 private Artifact unpackedArtifact;
60
5961 public ArtifactDownloadReport(Artifact artifact) {
6062 this.artifact = artifact;
6163 }
7375 }
7476
7577 /**
76 *
78 *
7779 * @return the type of the downloaded artifact
7880 */
7981 public String getType() {
124126 if (downloadStatus == DownloadStatus.SUCCESSFUL) {
125127 return "[SUCCESSFUL ] " + artifact + " (" + downloadTimeMillis + "ms)";
126128 } else if (downloadStatus == DownloadStatus.FAILED) {
127 if (downloadDetails == MISSING_ARTIFACT) {
129 if (MISSING_ARTIFACT.equals(downloadDetails)) {
128130 return "[NOT FOUND ] " + artifact + " (" + downloadTimeMillis + "ms)";
129131 } else {
130132 return "[FAILED ] " + artifact + ": " + downloadDetails + " ("
140142 /**
141143 * Returns the File where the artifact is available on the local filesystem, or
142144 * <code>null</code> if and only if the artifact caching failed.
143 *
145 *
144146 * @return the file where the artifact is now available on the local filesystem.
145147 */
146148 public File getLocalFile() {
163165 return unpackedLocalFile;
164166 }
165167
168 public void setUnpackedArtifact(final Artifact unpackedArtifact) {
169 this.unpackedArtifact = unpackedArtifact;
170 }
171
172 public Artifact getUnpackedArtifact() {
173 return this.unpackedArtifact;
174 }
175
166176 public int hashCode() {
167177 final int prime = 31;
168178 int result = 1;
171181 }
172182
173183 public boolean equals(Object obj) {
184 if (!(obj instanceof ArtifactDownloadReport)) {
185 return false;
186 }
174187 if (this == obj) {
175188 return true;
176189 }
177 if (obj == null) {
178 return false;
179 }
180 if (getClass() != obj.getClass()) {
181 return false;
182 }
183190 ArtifactDownloadReport other = (ArtifactDownloadReport) obj;
184 if (artifact == null) {
185 if (other.artifact != null) {
186 return false;
187 }
188 } else if (!artifact.equals(other.artifact)) {
189 return false;
190 }
191 return true;
191 return artifact == null ? other.artifact == null : artifact.equals(other.artifact);
192192 }
193193
194194 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5555
5656 private final ResolveOptions options;
5757
58 private Map<IvyNode, List<ArtifactDownloadReport>> dependencyReports = new LinkedHashMap<IvyNode, List<ArtifactDownloadReport>>();
59
60 private Map<ModuleRevisionId, IvyNode> dependencies = new LinkedHashMap<ModuleRevisionId, IvyNode>();
58 private Map<IvyNode, List<ArtifactDownloadReport>> dependencyReports = new LinkedHashMap<>();
59
60 private Map<ModuleRevisionId, IvyNode> dependencies = new LinkedHashMap<>();
6161
6262 private final ResolveEngine resolveEngine;
6363
64 private Map<ModuleId, Collection<IvyNode>> modulesIdsMap = new LinkedHashMap<ModuleId, Collection<IvyNode>>();
64 private Map<ModuleId, Collection<IvyNode>> modulesIdsMap = new LinkedHashMap<>();
6565
6666 private List<ModuleId> modulesIds;
6767
7777 }
7878
7979 /**
80 * Check if the set of dependencies has changed since the previous execution of a resolution.<br/>
80 * Check if the set of dependencies has changed since the previous execution of a resolution.
81 * <p>
8182 * This function use the report file found in the cache. So the function must be called before
82 * the new report is serialized there.</br> This function also use the internal dependencies
83 * that must already be filled. This function might be 'heavy' because it may have to parse the
84 * previous report.
85 *
86 * @return
83 * the new report is serialized there.
84 * </p>
85 * <p>
86 * This function also use the internal dependencies that must already be filled. This function
87 * might be 'heavy' because it may have to parse the previous report.
88 * </p>
8789 */
8890 public void checkIfChanged() {
8991 ResolutionCacheManager cache = resolveEngine.getSettings().getResolutionCacheManager();
9395 try {
9496 XmlReportParser parser = new XmlReportParser();
9597 parser.parse(previousReportFile);
96 List<ModuleRevisionId> previousDeps = Arrays.asList(parser
97 .getDependencyRevisionIds());
98 HashSet<ModuleRevisionId> previousDepSet = new HashSet<ModuleRevisionId>(
99 previousDeps);
100 hasChanged = Boolean.valueOf(!previousDepSet.equals(getModuleRevisionIds()));
98 Set<ModuleRevisionId> previousDepSet = new HashSet<>(
99 Arrays.asList(parser.getDependencyRevisionIds()));
100 hasChanged = !previousDepSet.equals(getModuleRevisionIds());
101101 } catch (Exception e) {
102102 Message.warn("Error while parsing configuration resolve report "
103103 + previousReportFile.getAbsolutePath(), e);
110110
111111 /**
112112 * @pre checkIfChanged has been called.
113 * @return boolean
113114 */
114115 public boolean hasChanged() {
115 return hasChanged.booleanValue();
116 return hasChanged;
116117 }
117118
118119 /**
119120 * Returns all non evicted and non error dependency mrids The returned set is ordered so that a
120121 * dependency will always be found before their own dependencies
121 *
122 *
122123 * @return all non evicted and non error dependency mrids
123124 */
124125 public Set<ModuleRevisionId> getModuleRevisionIds() {
125 Set<ModuleRevisionId> mrids = new LinkedHashSet<ModuleRevisionId>();
126 Set<ModuleRevisionId> mrids = new LinkedHashSet<>();
126127 for (IvyNode node : getDependencies()) {
127128 if (!node.isEvicted(getConfiguration()) && !node.hasProblem()) {
128129 mrids.add(node.getResolvedId());
144145 public void addDependency(IvyNode node, DownloadReport report) {
145146 dependencies.put(node.getId(), node);
146147 dependencies.put(node.getResolvedId(), node);
147 List<ArtifactDownloadReport> adrs = new ArrayList<ArtifactDownloadReport>();
148 Artifact[] artifacts = node.getArtifacts(conf);
149 for (Artifact artifact : artifacts) {
148 List<ArtifactDownloadReport> adrs = new ArrayList<>();
149 for (Artifact artifact : node.getArtifacts(conf)) {
150150 ArtifactDownloadReport artifactReport = report.getArtifactReport(artifact);
151151 if (artifactReport != null) {
152152 adrs.add(artifactReport);
169169 return md;
170170 }
171171
172 public ResolveOptions getResolveOptions() {
173 return options;
174 }
175
172176 public IvyNode[] getUnresolvedDependencies() {
173 List<IvyNode> unresolved = new ArrayList<IvyNode>();
177 List<IvyNode> unresolved = new ArrayList<>();
174178 for (IvyNode node : getDependencies()) {
175179 if (node.hasProblem()) {
176180 unresolved.add(node);
180184 }
181185
182186 private Collection<IvyNode> getDependencies() {
183 return new LinkedHashSet<IvyNode>(dependencies.values());
187 return new LinkedHashSet<>(dependencies.values());
184188 }
185189
186190 public IvyNode[] getEvictedNodes() {
187 List<IvyNode> evicted = new ArrayList<IvyNode>();
191 List<IvyNode> evicted = new ArrayList<>();
188192 for (IvyNode node : getDependencies()) {
189193 if (node.isEvicted(conf)) {
190194 evicted.add(node);
194198 }
195199
196200 private Set<ModuleRevisionId> getEvictedMrids() {
197 Set<ModuleRevisionId> evicted = new LinkedHashSet<ModuleRevisionId>();
198 IvyNode[] evictedNodes = getEvictedNodes();
199 for (IvyNode node : evictedNodes) {
201 Set<ModuleRevisionId> evicted = new LinkedHashSet<>();
202 for (IvyNode node : getEvictedNodes()) {
200203 evicted.add(node.getId());
201204 }
202205 return evicted;
203206 }
204207
205208 public IvyNode[] getDownloadedNodes() {
206 List<IvyNode> downloaded = new ArrayList<IvyNode>();
209 List<IvyNode> downloaded = new ArrayList<>();
207210 for (IvyNode node : getDependencies()) {
208211 if (node.isDownloaded() && node.getRealNode() == node) {
209212 downloaded.add(node);
213216 }
214217
215218 public IvyNode[] getSearchedNodes() {
216 List<IvyNode> downloaded = new ArrayList<IvyNode>();
219 List<IvyNode> downloaded = new ArrayList<>();
217220 for (IvyNode node : getDependencies()) {
218221 if (node.isSearched() && node.getRealNode() == node) {
219222 downloaded.add(node);
236239
237240 /**
238241 * gives all the modules ids concerned by this report, from the most dependent to the least one
239 *
242 *
240243 * @return a list of ModuleId
241244 */
242245 public List<ModuleId> getModuleIds() {
248251 ModuleId mid = dependency.getResolvedId().getModuleId();
249252 Collection<IvyNode> deps = modulesIdsMap.get(mid);
250253 if (deps == null) {
251 deps = new LinkedHashSet<IvyNode>();
254 deps = new LinkedHashSet<>();
252255 modulesIdsMap.put(mid, deps);
253256 }
254257 deps.add(dependency);
255258 }
256 modulesIds = new ArrayList<ModuleId>(modulesIdsMap.keySet());
259 modulesIds = new ArrayList<>(modulesIdsMap.keySet());
257260 }
258261 return Collections.unmodifiableList(modulesIds);
259262 }
279282
280283 /**
281284 * Get every report on the download requests.
282 *
285 *
283286 * @return the list of reports, never <code>null</code>
284287 */
285288 public ArtifactDownloadReport[] getAllArtifactsReports() {
289292 /**
290293 * Get the report on the download requests. The list of download report can be restricted to a
291294 * specific download status, and also remove the download report for the evicted modules.
292 *
295 *
293296 * @param downloadStatus
294 * the status of download to retreive. Set it to <code>null</code> for no restriction
297 * the status of download to retrieve. Set it to <code>null</code> for no restriction
295298 * on the download status
296299 * @param withEvicted
297300 * set it to <code>true</code> if the report for the evicted modules have to be
301304 */
302305 public ArtifactDownloadReport[] getArtifactsReports(DownloadStatus downloadStatus,
303306 boolean withEvicted) {
304 Collection<ArtifactDownloadReport> all = new LinkedHashSet<ArtifactDownloadReport>();
307 Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
305308 Collection<ModuleRevisionId> evictedMrids = null;
306309 if (!withEvicted) {
307310 evictedMrids = getEvictedMrids();
321324 }
322325
323326 /**
324 * Get the report on the sucessfull download requests with the evicted modules
325 *
327 * Get the report on the successful download requests with the evicted modules
328 *
326329 * @return the list of reports, never <code>null</code>
327330 */
328331 public ArtifactDownloadReport[] getDownloadedArtifactsReports() {
331334
332335 /**
333336 * Get the report on the failed download requests with the evicted modules
334 *
337 *
335338 * @return the list of reports, never <code>null</code>
336339 */
337340 public ArtifactDownloadReport[] getFailedArtifactsReports() {
349352
350353 public static ArtifactDownloadReport[] filterOutMergedArtifacts(
351354 ArtifactDownloadReport[] allFailedReports) {
352 Collection<ArtifactDownloadReport> adrs = new ArrayList<ArtifactDownloadReport>(
355 Collection<ArtifactDownloadReport> adrs = new ArrayList<>(
353356 Arrays.asList(allFailedReports));
354 for (Iterator<ArtifactDownloadReport> iterator = adrs.iterator(); iterator.hasNext();) {
357 Iterator<ArtifactDownloadReport> iterator = adrs.iterator();
358 while (iterator.hasNext()) {
355359 ArtifactDownloadReport adr = iterator.next();
356360
357361 if (adr.getArtifact().getExtraAttribute("ivy:merged") != null) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.List;
2322 import java.util.Map;
2423
2827 *
2928 */
3029 public class DownloadReport {
31 private Map artifacts = new HashMap();
30 private final Map<Artifact, ArtifactDownloadReport> artifacts = new HashMap<>();
3231
3332 public void addArtifactReport(ArtifactDownloadReport adr) {
3433 artifacts.put(adr.getArtifact(), adr);
3534 }
3635
3736 public ArtifactDownloadReport[] getArtifactsReports() {
38 return (ArtifactDownloadReport[]) artifacts.values().toArray(
39 new ArtifactDownloadReport[artifacts.size()]);
37 return artifacts.values().toArray(new ArtifactDownloadReport[artifacts.size()]);
4038 }
4139
4240 public ArtifactDownloadReport[] getArtifactsReports(DownloadStatus status) {
43 List ret = new ArrayList(artifacts.size());
44 for (Iterator iter = artifacts.values().iterator(); iter.hasNext();) {
45 ArtifactDownloadReport adr = (ArtifactDownloadReport) iter.next();
41 List<ArtifactDownloadReport> ret = new ArrayList<>(artifacts.size());
42 for (ArtifactDownloadReport adr : artifacts.values()) {
4643 if (adr.getDownloadStatus() == status) {
4744 ret.add(adr);
4845 }
4946 }
50 return (ArtifactDownloadReport[]) ret.toArray(new ArtifactDownloadReport[ret.size()]);
47 return ret.toArray(new ArtifactDownloadReport[ret.size()]);
5148 }
5249
5350 public ArtifactDownloadReport getArtifactReport(Artifact artifact) {
54 return (ArtifactDownloadReport) artifacts.get(artifact);
51 return artifacts.get(artifact);
5552 }
5653 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3737
3838 /**
3939 * Returns the {@link DownloadStatus} corresponding to the given String representation.
40 *
40 *
41 * @param status String
4142 * @return the {@link DownloadStatus} corresponding to the given String representation.
4243 * @throws IllegalArgumentException
4344 * if the given String does not correspond to any {@link DownloadStatus}.
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232 /**
3333 * Returns <code>true</code> if the resolution of this metadata artifact required at least one
3434 * access to the repository, or <code>false</code> if only provisioned data was used.
35 *
35 *
3636 * @return <code>true</code> if the resolution of this metadata artifact required at least one
3737 * access to the repository
3838 */
4747 /**
4848 * Returns the location on the local filesystem where the original metadata artifact is
4949 * provisioned, or <code>null</code> if the provisioning failed.
50 *
50 *
5151 * @return the location on the local filesystem where the original metadata artifact is
5252 * provisioned.
5353 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.util.Collection;
2323 import java.util.Date;
2424 import java.util.HashSet;
25 import java.util.Iterator;
2625 import java.util.LinkedHashMap;
2726 import java.util.LinkedHashSet;
2827 import java.util.List;
3029 import java.util.Set;
3130
3231 import org.apache.ivy.core.cache.ResolutionCacheManager;
32 import org.apache.ivy.core.module.descriptor.Artifact;
3333 import org.apache.ivy.core.module.descriptor.Configuration;
3434 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
3535 import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
36 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3736 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3837 import org.apache.ivy.core.module.id.ModuleId;
3938 import org.apache.ivy.core.module.id.ModuleRevisionId;
4948 public class ResolveReport {
5049 private ModuleDescriptor md;
5150
52 /** String conf -> ConfigurationResolveReport report */
53 private Map confReports = new LinkedHashMap();
54
55 private List problemMessages = new ArrayList();
51 private Map<String, ConfigurationResolveReport> confReports = new LinkedHashMap<>();
52
53 private List<String> problemMessages = new ArrayList<>();
5654
5755 /**
5856 * the list of all dependencies resolved, ordered from the more dependent to the less dependent
5957 */
60 private List/* <IvyNode> */dependencies = new ArrayList();
61
62 private List/* <Artifact> */artifacts = new ArrayList();
58 private List<IvyNode> dependencies = new ArrayList<>();
59
60 private List<Artifact> artifacts = new ArrayList<>();
6361
6462 private long resolveTime;
6563
8381 }
8482
8583 public ConfigurationResolveReport getConfigurationReport(String conf) {
86 return (ConfigurationResolveReport) confReports.get(conf);
84 return confReports.get(conf);
8785 }
8886
8987 public String[] getConfigurations() {
90 return (String[]) confReports.keySet().toArray(new String[confReports.size()]);
88 return confReports.keySet().toArray(new String[confReports.size()]);
9189 }
9290
9391 public boolean hasError() {
94 boolean hasError = false;
95 for (Iterator it = confReports.values().iterator(); it.hasNext() && !hasError;) {
96 ConfigurationResolveReport report = (ConfigurationResolveReport) it.next();
97 hasError |= report.hasError();
98 }
99 return hasError;
92 for (ConfigurationResolveReport report : confReports.values()) {
93 if (report.hasError()) {
94 return true;
95 }
96 }
97 return false;
10098 }
10199
102100 public void output(ReportOutputter[] outputters, ResolutionCacheManager cacheMgr,
103101 ResolveOptions options) throws IOException {
104 for (int i = 0; i < outputters.length; i++) {
105 outputters[i].output(this, cacheMgr, options);
102 for (ReportOutputter outputter : outputters) {
103 outputter.output(this, cacheMgr, options);
106104 }
107105 }
108106
111109 }
112110
113111 public IvyNode[] getEvictedNodes() {
114 Collection all = new LinkedHashSet();
115 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
116 ConfigurationResolveReport report = (ConfigurationResolveReport) iter.next();
112 Collection<IvyNode> all = new LinkedHashSet<>();
113 for (ConfigurationResolveReport report : confReports.values()) {
117114 all.addAll(Arrays.asList(report.getEvictedNodes()));
118115 }
119 return (IvyNode[]) all.toArray(new IvyNode[all.size()]);
116 return all.toArray(new IvyNode[all.size()]);
120117 }
121118
122119 public IvyNode[] getUnresolvedDependencies() {
123 Collection all = new LinkedHashSet();
124 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
125 ConfigurationResolveReport report = (ConfigurationResolveReport) iter.next();
120 Collection<IvyNode> all = new LinkedHashSet<>();
121 for (ConfigurationResolveReport report : confReports.values()) {
126122 all.addAll(Arrays.asList(report.getUnresolvedDependencies()));
127123 }
128 return (IvyNode[]) all.toArray(new IvyNode[all.size()]);
124 return all.toArray(new IvyNode[all.size()]);
129125 }
130126
131127 /**
132128 * Get every report on the download requests.
133 *
129 *
134130 * @return the list of reports, never <code>null</code>
135131 */
136132 public ArtifactDownloadReport[] getFailedArtifactsReports() {
140136
141137 /**
142138 * Get every report on the download requests.
143 *
139 *
144140 * @return the list of reports, never <code>null</code>
145141 */
146142 public ArtifactDownloadReport[] getAllArtifactsReports() {
150146 /**
151147 * Get the report on the download requests. The list of download report can be restricted to a
152148 * specific download status, and also remove the download report for the evicted modules.
153 *
149 *
154150 * @param downloadStatus
155 * the status of download to retreive. Set it to <code>null</code> for no restriction
151 * the status of download to retrieve. Set it to <code>null</code> for no restriction
156152 * on the download status
157153 * @param withEvicted
158154 * set it to <code>true</code> if the report for the evicted modules have to be
163159 */
164160 public ArtifactDownloadReport[] getArtifactsReports(DownloadStatus downloadStatus,
165161 boolean withEvicted) {
166 Collection all = new LinkedHashSet();
167 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
168 ConfigurationResolveReport report = (ConfigurationResolveReport) iter.next();
162 Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
163 for (ConfigurationResolveReport report : confReports.values()) {
169164 ArtifactDownloadReport[] reports = report.getArtifactsReports(downloadStatus,
170165 withEvicted);
171166 all.addAll(Arrays.asList(reports));
172167 }
173 return (ArtifactDownloadReport[]) all.toArray(new ArtifactDownloadReport[all.size()]);
168 return all.toArray(new ArtifactDownloadReport[all.size()]);
174169 }
175170
176171 public ArtifactDownloadReport[] getArtifactsReports(ModuleRevisionId mrid) {
177 Collection all = new LinkedHashSet();
178 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
179 ConfigurationResolveReport report = (ConfigurationResolveReport) iter.next();
172 Collection<ArtifactDownloadReport> all = new LinkedHashSet<>();
173 for (ConfigurationResolveReport report : confReports.values()) {
180174 all.addAll(Arrays.asList(report.getDownloadReports(mrid)));
181175 }
182 return (ArtifactDownloadReport[]) all.toArray(new ArtifactDownloadReport[all.size()]);
176 return all.toArray(new ArtifactDownloadReport[all.size()]);
183177 }
184178
185179 public void checkIfChanged() {
186 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
187 ConfigurationResolveReport report = (ConfigurationResolveReport) iter.next();
180 for (ConfigurationResolveReport report : confReports.values()) {
188181 report.checkIfChanged();
189182 }
190183 }
191184
192 /** Can only be called if checkIfChanged has been called */
185 /**
186 * Can only be called if checkIfChanged has been called
187 *
188 * @return boolean
189 */
193190 public boolean hasChanged() {
194 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
195 ConfigurationResolveReport report = (ConfigurationResolveReport) iter.next();
191 for (ConfigurationResolveReport report : confReports.values()) {
196192 if (report.hasChanged()) {
197193 return true;
198194 }
200196 return false;
201197 }
202198
203 public void setProblemMessages(List problems) {
199 public void setProblemMessages(List<String> problems) {
204200 problemMessages = problems;
205201 }
206202
207 public List getProblemMessages() {
203 public List<String> getProblemMessages() {
208204 return problemMessages;
209205 }
210206
211 public List getAllProblemMessages() {
212 List ret = new ArrayList(problemMessages);
213 for (Iterator iter = confReports.values().iterator(); iter.hasNext();) {
214 ConfigurationResolveReport r = (ConfigurationResolveReport) iter.next();
215 IvyNode[] unresolved = r.getUnresolvedDependencies();
216 for (int i = 0; i < unresolved.length; i++) {
217 String errMsg = unresolved[i].getProblemMessage();
218 if (errMsg.length() > 0) {
219 ret.add("unresolved dependency: " + unresolved[i].getId() + ": " + errMsg);
207 public List<String> getAllProblemMessages() {
208 List<String> ret = new ArrayList<>(problemMessages);
209 for (ConfigurationResolveReport r : confReports.values()) {
210 for (IvyNode unresolved : r.getUnresolvedDependencies()) {
211 String errMsg = unresolved.getProblemMessage();
212 if (errMsg.isEmpty()) {
213 ret.add("unresolved dependency: " + unresolved.getId());
220214 } else {
221 ret.add("unresolved dependency: " + unresolved[i].getId());
215 ret.add("unresolved dependency: " + unresolved.getId() + ": " + errMsg);
222216 }
223217 }
224 ArtifactDownloadReport[] adrs = r.getFailedArtifactsReports();
225 for (int i = 0; i < adrs.length; i++) {
226 ret.add("download failed: " + adrs[i].getArtifact());
218 for (ArtifactDownloadReport adr : r.getFailedArtifactsReports()) {
219 ret.add("download failed: " + adr.getArtifact());
227220 }
228221 }
229222 return ret;
230223 }
231224
232 public void setDependencies(List dependencies, Filter artifactFilter) {
225 public void setDependencies(List<IvyNode> dependencies, Filter<Artifact> artifactFilter) {
233226 this.dependencies = dependencies;
234227 // collect list of artifacts
235 artifacts = new ArrayList();
236 for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
237 IvyNode dependency = (IvyNode) iter.next();
228 artifacts = new ArrayList<>();
229 for (IvyNode dependency : dependencies) {
238230 if (!dependency.isCompletelyEvicted() && !dependency.hasProblem()) {
239231 artifacts.addAll(Arrays.asList(dependency.getSelectedArtifacts(artifactFilter)));
240232 }
241233 // update the configurations reports with the dependencies
242234 // these reports will be completed later with download information, if any
243 String[] dconfs = dependency.getRootModuleConfigurations();
244 for (int j = 0; j < dconfs.length; j++) {
245 ConfigurationResolveReport configurationReport = getConfigurationReport(dconfs[j]);
235 for (String dconf : dependency.getRootModuleConfigurations()) {
236 ConfigurationResolveReport configurationReport = getConfigurationReport(dconf);
246237 if (configurationReport != null) {
247238 configurationReport.addDependency(dependency);
248239 }
253244 /**
254245 * Returns the list of all dependencies concerned by this report as a List of IvyNode ordered
255246 * from the more dependent to the least one
256 *
247 *
257248 * @return The list of all dependencies.
258249 */
259 public List/* <IvyNode> */getDependencies() {
250 public List<IvyNode> getDependencies() {
260251 return dependencies;
261252 }
262253
263254 /**
264255 * Returns the list of all artifacts which should be downloaded per this resolve To know if the
265256 * artifact have actually been downloaded use information found in ConfigurationResolveReport.
266 *
257 *
267258 * @return The list of all artifacts.
268259 */
269 public List/* <Artifact> */getArtifacts() {
260 public List<Artifact> getArtifacts() {
270261 return artifacts;
271262 }
272263
273264 /**
274265 * gives all the modules ids concerned by this report, from the most dependent to the least one
275 *
266 *
276267 * @return a list of ModuleId
277268 */
278 public List getModuleIds() {
279 List ret = new ArrayList();
280 List sortedDependencies = new ArrayList(dependencies);
281 for (Iterator iter = sortedDependencies.iterator(); iter.hasNext();) {
282 IvyNode dependency = (IvyNode) iter.next();
269 public List<ModuleId> getModuleIds() {
270 List<ModuleId> ret = new ArrayList<>();
271 List<IvyNode> sortedDependencies = new ArrayList<>(dependencies);
272 for (IvyNode dependency : sortedDependencies) {
283273 ModuleId mid = dependency.getResolvedId().getModuleId();
284274 if (!ret.contains(mid)) {
285275 ret.add(mid);
314304 * This only includes artifacts actually downloaded to cache (DownloadStatus.SUCCESSFUL), and
315305 * not artifacts already in cache or used at their original location.
316306 * </p>
317 *
307 *
318308 * @return The total size of downloaded artifacts, in bytes.
319309 */
320310 public long getDownloadSize() {
328318 /**
329319 * Get every configuration which extends the specified one. The returned list also includes the
330320 * specified one.
331 *
332 * @param extended
333 * @return
334 */
335 private String[] getExtendingConfs(String extended) {
336 String[] allConfs = md.getConfigurationsNames();
337 Set<String> extendingConfs = new HashSet<String>();
321 *
322 * @param extended String
323 * @return Set of String
324 */
325 @SuppressWarnings("unused")
326 private Set<String> getExtendingConfs(String extended) {
327 Set<String> extendingConfs = new HashSet<>();
338328 extendingConfs.add(extended);
339 for (int i = 0; i < allConfs.length; i++) {
340 gatherExtendingConfs(extendingConfs, allConfs[i], extended);
341 }
342 return extendingConfs.toArray(new String[extendingConfs.size()]);
329 for (String conf : md.getConfigurationsNames()) {
330 gatherExtendingConfs(extendingConfs, conf, extended);
331 }
332 return extendingConfs;
343333 }
344334
345335 private boolean gatherExtendingConfs(Set<String> extendingConfs, String conf, String extended) {
346336 if (extendingConfs.contains(conf)) {
347337 return true;
348338 }
349 String[] ext = md.getConfiguration(conf).getExtends();
350 if (ext == null || ext.length == 0) {
339 String[] exts = md.getConfiguration(conf).getExtends();
340 if (exts == null || exts.length == 0) {
351341 return false;
352342 }
353 for (int i = 0; i < ext.length; i++) {
354 if (extendingConfs.contains(ext[i])) {
343 for (String ext : exts) {
344 if (extendingConfs.contains(ext)) {
355345 extendingConfs.add(conf);
356346 return true;
357347 }
358 if (ext[i].equals(extended)) {
348 if (ext.equals(extended)) {
359349 extendingConfs.add(conf);
360350 return true;
361351 }
362 if (gatherExtendingConfs(extendingConfs, ext[i], extended)) {
352 if (gatherExtendingConfs(extendingConfs, ext, extended)) {
363353 extendingConfs.add(conf);
364354 return true;
365355 }
370360 public ModuleDescriptor toFixedModuleDescriptor(IvySettings settings, List<ModuleId> midToKeep) {
371361 DefaultModuleDescriptor fixedmd = new DefaultModuleDescriptor(md.getModuleRevisionId(),
372362 md.getStatus(), new Date());
363
364 // copy namespaces
365 for (Map.Entry<String, String> ns : md.getExtraAttributesNamespaces().entrySet()) {
366 fixedmd.addExtraAttributeNamespace(ns.getKey(), ns.getValue());
367 }
368
369 // copy info
370 fixedmd.setDescription(md.getDescription());
371 fixedmd.setHomePage(md.getHomePage());
373372 fixedmd.getExtraInfos().addAll(md.getExtraInfos());
374373
375374 // copy configurations
378377 fixedmd.addConfiguration(new Configuration(conf));
379378 }
380379
381 if (midToKeep != null && !midToKeep.isEmpty()) {
382 // add dependency we want to keep from the original module descriptor
383 DependencyDescriptor[] deps = md.getDependencies();
384 for (int i = 0; i < deps.length; i++) {
385 if (midToKeep.contains(deps[i].getDependencyId())) {
386 DefaultDependencyDescriptor dep = new DefaultDependencyDescriptor(fixedmd,
387 deps[i].getDependencyRevisionId(), true, false, false);
388 List<String> confs = Arrays.asList(deps[i].getModuleConfigurations());
389 if (confs.size() == 1 && confs.get(0).equals("*")) {
390 confs = resolvedConfs;
391 }
392 for (String conf : confs) {
393 String[] extendedConfs = getExtendingConfs(conf);
394 String[] depConfs = deps[i].getDependencyConfigurations(conf);
395 for (String extendedConf : extendedConfs) {
396 if (resolvedConfs.contains(extendedConf)) {
397 for (String depConf : depConfs) {
398 dep.addDependencyConfiguration(extendedConf, depConf);
399 }
400 }
401 }
402 }
403 fixedmd.addDependency(dep);
404 }
380 // copy artifacts
381 for (String conf : resolvedConfs) {
382 for (Artifact a : md.getArtifacts(conf)) {
383 fixedmd.addArtifact(conf, a);
405384 }
406385 }
407386
408387 // add resolved dependencies
409 for (int i = 0; i < dependencies.size(); i++) {
410 IvyNode node = (IvyNode) dependencies.get(i);
411 if (midToKeep != null && midToKeep.contains(node.getModuleId())) {
412 continue;
413 }
414 String[] rootConfs = node.getRootModuleConfigurations();
415 for (int j = 0; j < rootConfs.length; j++) {
416 if (node.isEvicted(rootConfs[j])) {
388 for (IvyNode dep : dependencies) {
389 ModuleRevisionId depMrid;
390 boolean force;
391 if (midToKeep != null && midToKeep.contains(dep.getModuleId())) {
392 depMrid = dep.getId();
393 force = false;
394 } else {
395 depMrid = dep.getResolvedId();
396 force = true;
397 }
398 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(fixedmd, depMrid,
399 force, false, false);
400 boolean evicted = true;
401 for (String rootConf : dep.getRootModuleConfigurations()) {
402 if (dep.isEvicted(rootConf)) {
417403 continue;
418404 }
419 if (node.getAllArtifacts().length == 0) {
420 // no artifact: it was probably useful transitively, hence it is useless here
421 break;
405 evicted = false;
406 for (String targetConf : dep.getConfigurations(rootConf)) {
407 dd.addDependencyConfiguration(rootConf, targetConf);
422408 }
423 DefaultDependencyDescriptor dep = new DefaultDependencyDescriptor(fixedmd,
424 node.getResolvedId(), true, false, false);
425 String[] targetConfs = node.getConfigurations(rootConfs[j]);
426 for (int k = 0; k < targetConfs.length; k++) {
427 dep.addDependencyConfiguration(rootConfs[j], targetConfs[k]);
428 }
429 fixedmd.addDependency(dep);
409 }
410 if (!evicted) {
411 fixedmd.addDependency(dd);
430412 }
431413 }
432414
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.Comparator;
2222 import java.util.HashMap;
2323 import java.util.HashSet;
24 import java.util.Iterator;
24 import java.util.List;
2525 import java.util.Map;
2626 import java.util.TreeSet;
2727
2828 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
2929 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3030 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
31 import org.apache.ivy.core.module.id.ModuleId;
3132 import org.apache.ivy.core.module.id.ModuleRevisionId;
3233 import org.apache.ivy.core.resolve.ResolveData;
3334 import org.apache.ivy.core.resolve.ResolveEngine;
6162 * </p>
6263 * <p>
6364 * This engine is not intended to be used concurrently with publish, the order of repository loaded
64 * being undeterministic and long, it could end up in having an inconsistent in memory state.
65 * being nondeterministic and long, it could end up in having an inconsistent in memory state.
6566 * </p>
6667 * <p>
6768 * For better performance, we strongly suggest using this engine with cache in useOrigin mode.
8485 /**
8586 * ModuleDescriptors stored by ModuleRevisionId
8687 */
87 private Map/* <ModuleRevisionId,ModuleDescriptor> */revisions = new HashMap();
88 private Map<ModuleRevisionId, ModuleDescriptor> revisions = new HashMap<>();
8889
8990 /**
9091 * ModuleRevisionId for which loading was not possible, with corresponding error message.
9192 */
92 private Map/* <ModuleRevisionId,String> */errors = new HashMap();
93
94 /**
95 * List of ModuleRevisionId per ModuleId.
96 */
97 private Map/* <ModuleId,Collection<ModuleRevisionId>> */modules = new HashMap();
93 private Map<ModuleRevisionId, String> errors = new HashMap<>();
94
95 /**
96 * List of ModuleDescriptor per ModuleId.
97 */
98 private Map<ModuleId, Collection<ModuleDescriptor>> modules = new HashMap<>();
9899
99100 // /////////////////////////////////////////
100101 // state loaded on #analyze()
108109 /**
109110 * Cache from requested module revision id to actual module revision id.
110111 */
111 private Map/* <ModuleRevisionId,ModuleRevisionId> */cache = new HashMap();
112 private Map<ModuleRevisionId, ModuleRevisionId> cache = new HashMap<>();
112113
113114 /**
114115 * list of dependers per ModuleRevisionId.
115116 */
116 private Map/* <ModuleRevisionId,List<ModuleRevisionId>> */dependers = new HashMap();
117 private Map<ModuleRevisionId, List<ModuleRevisionId>> dependers = new HashMap<>();
117118
118119 // /////////////////////////////////////////
119120 // dependencies
147148 Message.rawinfo("searching modules... ");
148149 ModuleRevisionId[] mrids = searchModules();
149150 Message.info("loading repository metadata...");
150 for (int i = 0; i < mrids.length; i++) {
151 for (ModuleRevisionId mrid : mrids) {
151152 try {
152 loadModuleRevision(mrids[i]);
153 loadModuleRevision(mrid);
153154 } catch (Exception e) {
154155 Message.debug(e);
155 errors.put(mrids[i], e.getMessage());
156 errors.put(mrid, e.getMessage());
156157 }
157158 }
158159 long endTime = System.currentTimeMillis();
159 Message.info("\nrepository loaded: "
160 + modules.size()
161 + " modules; "
162 + revisions.size()
163 + " revisions; "
164 + (settings.dumpMemoryUsage() ? (MemoryUtil.getUsedMemory() - startingMemoryUse)
165 / KILO + "kB; " : "") + (endTime - startTime) / THOUSAND + "s");
160 Message.info(String.format("%nrepository loaded: %d modules; %d revisions; %s%ss",
161 modules.size(), revisions.size(), settings.dumpMemoryUsage()
162 ? (MemoryUtil.getUsedMemory() - startingMemoryUse) / KILO + "kB; " : "",
163 (endTime - startTime) / THOUSAND));
166164 loaded = true;
167165 }
168166
172170 * This method may take a long time to proceed. It should never be called from event dispatch
173171 * thread in a GUI.
174172 * </p>
175 *
173 *
176174 * @throws IllegalStateException
177175 * if the repository has not been loaded yet
178176 * @see #load()
180178 public void analyze() {
181179 ensureLoaded();
182180 Message.info("\nanalyzing dependencies...");
183 for (Iterator iterator = revisions.values().iterator(); iterator.hasNext();) {
184 ModuleDescriptor md = (ModuleDescriptor) iterator.next();
185 DependencyDescriptor[] dds = md.getDependencies();
186 for (int i = 0; i < dds.length; i++) {
187 ModuleRevisionId dep = getDependency(dds[i]);
181 for (ModuleDescriptor md : revisions.values()) {
182 for (DependencyDescriptor dd : md.getDependencies()) {
183 ModuleRevisionId dep = getDependency(dd);
188184 if (dep == null) {
189 Message.warn("inconsistent repository: declared dependency not found: "
190 + dds[i]);
185 Message.warn("inconsistent repository: declared dependency not found: " + dd);
191186 } else {
192187 getDependers(dep).add(md.getModuleRevisionId());
193188 }
199194
200195 /**
201196 * Returns the number of Module Revision in the repository.
202 *
197 *
203198 * @return the number of module revisions in the repository.
204199 * @throws IllegalStateException
205200 * if the repository has not been loaded yet
212207
213208 /**
214209 * Returns the number of ModuleId in the repository.
215 *
210 *
216211 * @return the number of ModuleId in the repository.
217212 * @throws IllegalStateException
218213 * if the repository has not been loaded yet
225220
226221 /**
227222 * Returns Module Revisions which have no dependers.
228 *
223 *
229224 * @return a Collection of the {@link ModuleRevisionId} of module revisions which have no
230225 * dependers in the repository.
231226 * @throws IllegalStateException
232227 * if the repository has not been analyzed yet
233228 * @see #analyze()
234229 */
235 public Collection getOrphans() {
230 public Collection<ModuleRevisionId> getOrphans() {
236231 ensureAnalyzed();
237 Collection orphans = new HashSet(revisions.keySet());
232 Collection<ModuleRevisionId> orphans = new HashSet<>(revisions.keySet());
238233 orphans.removeAll(dependers.keySet());
239234 return orphans;
240235 }
241236
242237 private ModuleRevisionId[] searchModules() {
243 ModuleRevisionId[] mrids = searchEngine.listModules(ModuleRevisionId.newInstance(
238 return searchEngine.listModules(ModuleRevisionId.newInstance(
244239 PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION,
245240 PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION),
246241 RegexpPatternMatcher.INSTANCE);
247 return mrids;
248242 }
249243
250244 private ModuleRevisionId getDependency(DependencyDescriptor dd) {
251245 ModuleRevisionId askedMrid = dd.getDependencyRevisionId();
252246 VersionMatcher vmatcher = settings.getVersionMatcher();
253247 if (vmatcher.isDynamic(askedMrid)) {
254 ModuleRevisionId mrid = (ModuleRevisionId) cache.get(askedMrid);
248 ModuleRevisionId mrid = cache.get(askedMrid);
255249 if (mrid == null) {
256 Collection revs = getAllRevisions(askedMrid);
257 for (Iterator iterator = revs.iterator(); iterator.hasNext();) {
258 ModuleDescriptor md = (ModuleDescriptor) iterator.next();
250 for (ModuleDescriptor md : getAllRevisions(askedMrid)) {
259251 if (vmatcher.needModuleDescriptor(askedMrid, md.getResolvedModuleRevisionId())) {
260252 if (vmatcher.accept(askedMrid, md)) {
261253 mrid = md.getResolvedModuleRevisionId();
280272 }
281273 }
282274
283 private Collection getDependers(ModuleRevisionId id) {
284 Collection depders = (Collection) dependers.get(id);
275 private Collection<ModuleRevisionId> getDependers(ModuleRevisionId id) {
276 List<ModuleRevisionId> depders = dependers.get(id);
285277 if (depders == null) {
286 depders = new ArrayList();
278 depders = new ArrayList<>();
287279 dependers.put(id, depders);
288280 }
289281 return depders;
301293 Message.progress();
302294 }
303295
304 private Collection getAllRevisions(ModuleRevisionId id) {
305 Collection revisions = (Collection) modules.get(id.getModuleId());
296 private Collection<ModuleDescriptor> getAllRevisions(ModuleRevisionId id) {
297 Collection<ModuleDescriptor> revisions = modules.get(id.getModuleId());
306298 if (revisions == null) {
307 revisions = new TreeSet(new Comparator() {
308 public int compare(Object o1, Object o2) {
309 ModuleDescriptor md1 = (ModuleDescriptor) o1;
310 ModuleDescriptor md2 = (ModuleDescriptor) o2;
299 revisions = new TreeSet<>(new Comparator<ModuleDescriptor>() {
300 public int compare(ModuleDescriptor md1, ModuleDescriptor md2) {
311301 // we use reverse order compared to latest revision, to have latest revision
312302 // first
313303 return settings.getDefaultLatestStrategy().sort(new ArtifactInfo[] {md1, md2})
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.ivy.core.resolve.ResolveEngineSettings;
2020
2121 public interface RepositoryManagementEngineSettings extends ResolveEngineSettings {
22 public boolean dumpMemoryUsage();
22 boolean dumpMemoryUsage();
2323 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.core.resolve;
1818
19 import java.util.ArrayDeque;
1920 import java.util.ArrayList;
2021 import java.util.Arrays;
2122 import java.util.Collection;
23 import java.util.Collections;
24 import java.util.Deque;
2225 import java.util.HashMap;
2326 import java.util.HashSet;
2427 import java.util.Iterator;
5861 import org.apache.ivy.util.filter.Filter;
5962 import org.apache.ivy.util.filter.FilterHelper;
6063
61 public class IvyNode implements Comparable {
64 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PRIVATE;
65 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
66 import static org.apache.ivy.util.StringUtils.splitToArray;
67
68 public class IvyNode implements Comparable<IvyNode> {
6269 private static final Pattern FALLBACK_CONF_PATTERN = Pattern.compile("(.+)\\((.*)\\)");
6370
6471 // //////// CONTEXT
7986 private ModuleRevisionId id;
8087
8188 // set only when node has been built or updated from a DependencyDescriptor
82 // Map(IvyNode parent -> DependencyDescriptor)
83 private Map dds = new HashMap();
89 private Map<IvyNode, DependencyDescriptor> dds = new HashMap<>();
8490
8591 // Set when data has been loaded only, or when constructed from a module descriptor
8692 private ModuleDescriptor md;
94100
95101 private boolean searched = false;
96102
97 private Collection confsToFetch = new HashSet();
98
99 private Collection fetchedConfigurations = new HashSet();
100
101 private Collection loadedRootModuleConfs = new HashSet();
103 private Collection<String> confsToFetch = new HashSet<>();
104
105 private Collection<String> fetchedConfigurations = new HashSet<>();
106
107 private Collection<String> loadedRootModuleConfs = new HashSet<>();
102108
103109 // //////// USAGE DATA
104110
105111 private IvyNodeUsage usage = new IvyNodeUsage(this);
106112
107113 // usage information merged from evicted nodes this node is "replacing"
108 private Map/* <ModuleRevisionId, IvyNodeUsage> */mergedUsages = new LinkedHashMap();
114 private Map<ModuleRevisionId, IvyNodeUsage> mergedUsages = new LinkedHashMap<>();
109115
110116 public IvyNode(ResolveData data, IvyNode parent, DependencyDescriptor dd) {
111117 id = dd.getDependencyRevisionId();
130136
131137 /**
132138 * After the call node may be discarded. To avoid using discarded node, make sure to get the
133 * real node after the call IvyNode node = ... node.loadData(); node = node.getRealNode(); ...
139 * real node after the call
140 * <code>IvyNode node = ... node.loadData(); node = node.getRealNode(); ...</code>
141 *
142 * @param rootModuleConf String
143 * @param parent IvyNode
144 * @param parentConf String
145 * @param conf String
146 * @param shouldBePublic boolean
147 * @param usage IvyNodeUsage
148 * @return boolean
134149 */
135150 public boolean loadData(String rootModuleConf, IvyNode parent, String parentConf, String conf,
136151 boolean shouldBePublic, IvyNodeUsage usage) {
190205 if (settings.getVersionMatcher().isDynamic(getId())
191206 && settings.getVersionMatcher().isDynamic(module.getId())) {
192207 Message.error("impossible to resolve dynamic revision for " + getId()
193 + ": check your configuration and "
194 + "make sure revision is part of your pattern");
208 + ": check your configuration and make sure revision is part of your pattern");
195209 problem = new RuntimeException("impossible to resolve dynamic revision");
196210 return false;
197211 }
253267 if (hasProblem()) {
254268 Message.debug("problem : " + problem.getMessage());
255269 return false;
256 } else {
257 DependencyDescriptor dd = getDependencyDescriptor(parent);
258 if (dd != null) {
259 usage.addUsage(rootModuleConf, dd, parentConf);
260 }
261 return loaded;
262 }
270 }
271 DependencyDescriptor dd = getDependencyDescriptor(parent);
272 if (dd != null) {
273 usage.addUsage(rootModuleConf, dd, parentConf);
274 }
275 return loaded;
263276 }
264277
265278 private void moveToRealNode(String rootModuleConf, IvyNode parent, String parentConf,
288301 }
289302 }
290303
291 public Collection getDependencies(String rootModuleConf, String[] confs, String requestedConf) {
304 public Collection<IvyNode> getDependencies(String rootModuleConf, String[] confs,
305 String requestedConf) {
292306 if (md == null) {
293307 throw new IllegalStateException(
294308 "impossible to get dependencies when data has not been loaded");
300314 confs = md.getPublicConfigurationsNames();
301315 }
302316 }
303 Collection deps = new HashSet();
304 for (int i = 0; i < confs.length; i++) {
305 deps.addAll(getDependencies(rootModuleConf, confs[i], requestedConf));
317 Collection<IvyNode> deps = new HashSet<>();
318 for (String conf : confs) {
319 deps.addAll(getDependencies(rootModuleConf, conf, requestedConf));
306320 }
307321 return deps;
308322 }
311325 * Load the dependencies of the current node
312326 * <p>
313327 * The resulting collection of nodes may have some configuration to load
314 *
328 *
315329 * @param rootModuleConf
316330 * the requested configuration of the root module
317331 * @param conf
318332 * the configuration to load of this node
319333 * @param requestedConf
320334 * the actual node conf requested, possibly extending the <code>conf</code> one.
321 * @return
322 */
323 public Collection/* <IvyNode> */getDependencies(String rootModuleConf, String conf,
335 * @return {@link Collection} of {@link IvyNode}
336 */
337 public Collection<IvyNode> getDependencies(String rootModuleConf, String conf,
324338 String requestedConf) {
325339 if (md == null) {
326340 throw new IllegalStateException(
327341 "impossible to get dependencies when data has not been loaded");
328342 }
329 DependencyDescriptor[] dds = md.getDependencies();
330 Map/* <ModuleRevisionId, IvyNode> */dependencies = new LinkedHashMap(); // it's important to
331 // respect order
332 for (int i = 0; i < dds.length; i++) {
333 DependencyDescriptor dd = data.mediate(dds[i]);
343 // it's important to respect order => LinkedHashMap
344 Map<ModuleRevisionId, IvyNode> dependencies = new LinkedHashMap<>();
345 for (DependencyDescriptor dependencyDescriptor : md.getDependencies()) {
346 DependencyDescriptor dd = data.mediate(dependencyDescriptor);
334347 String[] dependencyConfigurations = dd.getDependencyConfigurations(conf, requestedConf);
335348 if (dependencyConfigurations.length == 0) {
336349 // no configuration of the dependency is required for current confs :
346359 }
347360
348361 // check if not already loaded here
349 IvyNode depNode = (IvyNode) dependencies.get(requestedDependencyRevisionId);
362 IvyNode depNode = dependencies.get(requestedDependencyRevisionId);
350363 if (depNode == null) {
351364 // check if not already loaded during the resolve session
352365 depNode = data.getNode(requestedDependencyRevisionId);
363376
364377 }
365378 String[] confsArray = depNode.resolveSpecialConfigurations(dependencyConfigurations);
366 Collection confs = Arrays.asList(confsArray);
379 Collection<String> confs = Arrays.asList(confsArray);
367380 depNode.updateConfsToFetch(confs);
368381 depNode.addRootModuleConfigurations(depNode.usage, rootModuleConf, confsArray);
369382 depNode.usage.setRequiredConfs(this, conf, confs);
380393 }
381394
382395 public DependencyDescriptor getDependencyDescriptor(IvyNode parent) {
383 return (DependencyDescriptor) dds.get(parent);
396 return dds.get(parent);
384397 }
385398
386399 private boolean isDependencyModuleExcluded(DependencyDescriptor dd, String rootModuleConf,
389402 if (isRoot()) {
390403 // no callers, but maybe some exclude
391404 Boolean exclude = doesExclude(md, rootModuleConf, new String[] {rootModuleConf}, dd, a,
392 new Stack());
393 return exclude == null ? false : exclude.booleanValue();
405 new ArrayDeque<IvyNode>());
406 return exclude != null && exclude;
394407 }
395408 return callers.doesCallersExclude(rootModuleConf, a);
396409 }
397410
398411 Boolean doesExclude(ModuleDescriptor md, String rootModuleConf, String[] moduleConfs,
399 DependencyDescriptor dd, Artifact artifact, Stack callersStack) {
412 DependencyDescriptor dd, Artifact artifact, Deque<IvyNode> callersStack) {
400413 // artifact is excluded if it match any of the exclude pattern for this dependency...
401 if (dd != null) {
402 if (dd.doesExclude(moduleConfs, artifact.getId().getArtifactId())) {
403 return Boolean.TRUE;
404 }
405 }
406 if (md.doesExclude(moduleConfs, artifact.getId().getArtifactId())) {
414 if (directlyExcludes(md, moduleConfs, dd, artifact)) {
407415 return Boolean.TRUE;
408416 }
409417 // ... or if it is excluded by all its callers
410418 IvyNode c = getData().getNode(md.getModuleRevisionId());
411419 if (c != null) {
412 if (callersStack.contains(c.getId())) {
420 if (callersStack.contains(c)) {
413421 // a circular dependency, we cannot be conclusive here
414422 return null;
415423 }
416 return Boolean.valueOf(c.doesCallersExclude(rootModuleConf, artifact, callersStack));
417 } else {
418 return Boolean.FALSE;
419 }
424 return c.doesCallersExclude(rootModuleConf, artifact, callersStack);
425 }
426 return Boolean.FALSE;
427 }
428
429 public boolean directlyExcludes(ModuleDescriptor md, String[] moduleConfs,
430 DependencyDescriptor dd, Artifact artifact) {
431 return dd != null && dd.doesExclude(moduleConfs, artifact.getId().getArtifactId())
432 || md.doesExclude(moduleConfs, artifact.getId().getArtifactId());
420433 }
421434
422435 public boolean hasConfigurationsToLoad() {
436449 if (md != null) {
437450 String[] confs = getRealConfs(conf);
438451 addRootModuleConfigurations(usage, rootModuleConf, confs);
439 for (int i = 0; i < confs.length; i++) {
440 Configuration c = md.getConfiguration(confs[i]);
452 for (String realConf : confs) {
453 Configuration c = md.getConfiguration(realConf);
441454 if (c == null) {
442455 confsToFetch.remove(conf);
443456 if (isConfRequiredByMergedUsageOnly(rootModuleConf, conf)) {
444457 Message.verbose("configuration required by evicted revision is not available in "
445458 + "selected revision. skipping " + conf + " in " + this);
446 } else if (!conf.equals(confs[i])) {
459 } else if (!conf.equals(realConf)) {
447460 problem = new RuntimeException("configuration not found in " + this + ": '"
448 + conf + "'. Missing configuration: '" + confs[i]
461 + conf + "'. Missing configuration: '" + realConf
449462 + "'. It was required from " + parent + " " + parentConf);
450463 } else {
451464 problem = new RuntimeException("configuration not found in " + this + ": '"
452 + confs[i] + "'. It was required from " + parent + " " + parentConf);
465 + realConf + "'. It was required from " + parent + " " + parentConf);
453466 }
454467 return false;
455 } else if (shouldBePublic && !isRoot()
456 && c.getVisibility() != Configuration.Visibility.PUBLIC) {
468 }
469 if (shouldBePublic && !isRoot() && !PUBLIC.equals(c.getVisibility())) {
457470 confsToFetch.remove(conf);
458471 if (isConfRequiredByMergedUsageOnly(rootModuleConf, conf)) {
459472 Message.verbose("configuration required by evicted revision is not visible in "
477490
478491 private String getDefaultConf(String conf) {
479492 Matcher m = FALLBACK_CONF_PATTERN.matcher(conf);
480 if (m.matches()) {
481 return m.group(2);
482 } else {
483 return conf;
484 }
493 return m.matches() ? m.group(2) : conf;
485494 }
486495
487496 private String getMainConf(String conf) {
488497 Matcher m = FALLBACK_CONF_PATTERN.matcher(conf);
489 if (m.matches()) {
490 return m.group(1);
491 } else {
492 return null;
493 }
494 }
495
496 public void updateConfsToFetch(Collection confs) {
498 return m.matches() ? m.group(1) : null;
499 }
500
501 public void updateConfsToFetch(Collection<String> confs) {
497502 confsToFetch.addAll(confs);
498503 confsToFetch.removeAll(fetchedConfigurations);
499504 }
509514 return getDescriptor().getPublicConfigurationsNames();
510515 }
511516 // there are exclusions in the configuration
512 List exclusions = Arrays.asList(conf.substring(2).split("\\!"));
513
514 List ret = new ArrayList(Arrays.asList(getDescriptor().getPublicConfigurationsNames()));
517 List<String> exclusions = Arrays.asList(conf.substring(2).split("\\!"));
518
519 List<String> ret = new ArrayList<>(Arrays.asList(getDescriptor()
520 .getPublicConfigurationsNames()));
515521 ret.removeAll(exclusions);
516522
517 return (String[]) ret.toArray(new String[ret.size()]);
523 return ret.toArray(new String[ret.size()]);
518524 }
519525 return dependencyConfigurations;
520526 }
521527
522528 /**
523529 * returns the required configurations from the given node
524 *
525 * @param in
526 * @return
530 *
531 * @param in IvyNode
532 * @param inConf ditto
533 * @return array of configuration names
527534 */
528535 public String[] getRequiredConfigurations(IvyNode in, String inConf) {
529 Collection req = new LinkedHashSet();
536 Collection<String> req = new LinkedHashSet<>();
530537 addAllIfNotNull(req, usage.getRequiredConfigurations(in, inConf));
531 for (Iterator iterator = mergedUsages.values().iterator(); iterator.hasNext();) {
532 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
538 for (IvyNodeUsage usage : mergedUsages.values()) {
533539 addAllIfNotNull(req, usage.getRequiredConfigurations(in, inConf));
534540 }
535 return req == null ? new String[0] : (String[]) req.toArray(new String[req.size()]);
536 }
537
538 private void addAllIfNotNull(Collection into, Collection col) {
541 return req.toArray(new String[req.size()]);
542 }
543
544 private <T> void addAllIfNotNull(Collection<T> into, Collection<T> col) {
539545 if (col != null) {
540546 into.addAll(col);
541547 }
543549
544550 /**
545551 * returns all the current required configurations of the node
546 *
547 * @return
552 *
553 * @return array of configuration names
548554 */
549555 public String[] getRequiredConfigurations() {
550 Collection required = new ArrayList(confsToFetch.size() + fetchedConfigurations.size());
556 Collection<String> required = new ArrayList<>(confsToFetch.size()
557 + fetchedConfigurations.size());
551558 required.addAll(fetchedConfigurations);
552559 required.addAll(confsToFetch);
553 return (String[]) required.toArray(new String[required.size()]);
560 return required.toArray(new String[required.size()]);
554561 }
555562
556563 public Configuration getConfiguration(String conf) {
569576
570577 /**
571578 * Returns the configurations of the dependency required in a given root module configuration.
572 *
573 * @param rootModuleConf
574 * @return
579 *
580 * @param rootModuleConf String
581 * @return array of configuration names
575582 */
576583 public String[] getConfigurations(String rootModuleConf) {
577 Set depConfs = new LinkedHashSet();
584 Set<String> depConfs = new LinkedHashSet<>();
578585 addAllIfNotNull(depConfs, usage.getConfigurations(rootModuleConf));
579 for (Iterator iterator = mergedUsages.values().iterator(); iterator.hasNext();) {
580 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
586 for (IvyNodeUsage usage : mergedUsages.values()) {
581587 addAllIfNotNull(depConfs, usage.getConfigurations(rootModuleConf));
582588 }
583 return (String[]) depConfs.toArray(new String[depConfs.size()]);
589 return depConfs.toArray(new String[depConfs.size()]);
584590 }
585591
586592 protected boolean isConfRequiredByMergedUsageOnly(String rootModuleConf, String conf) {
587 Set confs = usage.getConfigurations(rootModuleConf);
593 Set<String> confs = usage.getConfigurations(rootModuleConf);
588594 return confs == null || !confs.contains(conf);
589595 }
590596
591597 // This is never called. Could we remove it?
598 @Deprecated
592599 public void discardConf(String rootModuleConf, String conf) {
593 Set depConfs = usage.addAndGetConfigurations(rootModuleConf);
594 if (md != null) {
600 Set<String> depConfs = usage.addAndGetConfigurations(rootModuleConf);
601 if (md == null) {
602 depConfs.remove(conf);
603 } else {
595604 // remove all given dependency configurations to the set + extended ones
596605 Configuration c = md.getConfiguration(conf);
597 if (conf != null) {
598 String[] exts = c.getExtends();
599 for (int i = 0; i < exts.length; i++) {
600 discardConf(rootModuleConf, exts[i]); // recursive remove of extended
601 // configurations
606 if (conf == null) {
607 Message.warn("unknown configuration in " + getId() + ": " + conf);
608 } else {
609 // recursive remove of extended configurations
610 for (String ext : c.getExtends()) {
611 discardConf(rootModuleConf, ext);
602612 }
603613 depConfs.remove(c.getName());
604 } else {
605 Message.warn("unknown configuration in " + getId() + ": " + conf);
606 }
607 } else {
608 depConfs.remove(conf);
614 }
609615 }
610616 }
611617
612618 private void addRootModuleConfigurations(IvyNodeUsage usage, String rootModuleConf,
613619 String[] dependencyConfs) {
614 Set depConfs = usage.addAndGetConfigurations(rootModuleConf);
615620 if (md != null) {
616621 // add all given dependency configurations to the set + extended ones
617 for (int i = 0; i < dependencyConfs.length; i++) {
618 depConfs.add(dependencyConfs[i]);
619 Configuration conf = md.getConfiguration(dependencyConfs[i]);
622 for (String dependencyConf : dependencyConfs) {
623 Configuration conf = md.getConfiguration(dependencyConf);
620624 if (conf != null) {
621 String[] exts = conf.getExtends();
622625 // recursive add of extended
623 addRootModuleConfigurations(usage, rootModuleConf, exts);
626 addRootModuleConfigurations(usage, rootModuleConf, conf.getExtends());
624627 }
625628 }
626 } else {
627 for (int i = 0; i < dependencyConfs.length; i++) {
628 depConfs.add(dependencyConfs[i]);
629 }
630 }
629 }
630 Collections.addAll(usage.addAndGetConfigurations(rootModuleConf), dependencyConfs);
631631 }
632632
633633 /**
634634 * Returns the root module configurations in which this dependency is required
635 *
636 * @return
635 *
636 * @return array of configuration names
637637 */
638638 public String[] getRootModuleConfigurations() {
639 Set confs = getRootModuleConfigurationsSet();
640 return (String[]) confs.toArray(new String[confs.size()]);
639 Set<String> confs = getRootModuleConfigurationsSet();
640 return confs.toArray(new String[confs.size()]);
641641 }
642642
643643 /**
644644 * Returns the root module configurations in which this dependency is required
645 *
646 * @return
647 */
648 public Set getRootModuleConfigurationsSet() {
649 Set confs = new LinkedHashSet();
645 *
646 * @return {@link Set} of configuration names
647 */
648 public Set<String> getRootModuleConfigurationsSet() {
649 Set<String> confs = new LinkedHashSet<>();
650650 addAllIfNotNull(confs, usage.getRootModuleConfigurations());
651 for (Iterator iterator = mergedUsages.values().iterator(); iterator.hasNext();) {
652 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
651 for (IvyNodeUsage usage : mergedUsages.values()) {
653652 addAllIfNotNull(confs, usage.getRootModuleConfigurations());
654653 }
655654 return confs;
656655 }
657656
658657 public String[] getConfsToFetch() {
659 return (String[]) confsToFetch.toArray(new String[confsToFetch.size()]);
658 return confsToFetch.toArray(new String[confsToFetch.size()]);
660659 }
661660
662661 public String[] getRealConfs(String conf) {
665664 }
666665 String defaultConf = getDefaultConf(conf);
667666 conf = getMainConf(conf);
668 if ((md.getConfiguration(conf) == null)
669 || Configuration.Visibility.PRIVATE.equals(md.getConfiguration(conf)
670 .getVisibility())) {
667 if (md.getConfiguration(conf) == null
668 || PRIVATE.equals(md.getConfiguration(conf).getVisibility())) {
671669 if ("".equals(defaultConf)) {
672670 return new String[0];
673671 }
674672 conf = defaultConf;
675673 }
676 if (conf.startsWith("*")) {
674 if (conf.charAt(0) == '*') {
677675 return resolveSpecialConfigurations(new String[] {conf});
678 } else if (conf.indexOf(',') != -1) {
679 String[] confs = conf.split(",");
680 for (int i = 0; i < confs.length; i++) {
681 confs[i] = confs[i].trim();
682 }
676 }
677 if (conf.contains(",")) {
678 return splitToArray(conf);
683679 }
684680 return new String[] {conf};
685681
687683
688684 /**
689685 * Finds and returns a path in callers from the given module id to the current node
690 *
686 *
691687 * @param from
692688 * the module id to start the path from
693689 * @return a collection representing the path, starting with the from node, followed by the list
694690 * of nodes being one path to the current node, excluded
695691 */
696 private Collection findPath(ModuleId from) {
697 return findPath(from, this, new LinkedList());
698 }
699
700 private Collection findPath(ModuleId from, IvyNode node, List path) {
692 private Collection<IvyNode> findPath(ModuleId from) {
693 return findPath(from, this, new LinkedList<IvyNode>());
694 }
695
696 private Collection<IvyNode> findPath(ModuleId from, IvyNode node, List<IvyNode> path) {
701697 IvyNode parent = node.getDirectCallerFor(from);
702698 if (parent == null) {
703699 throw new IllegalArgumentException("no path from " + from + " to " + getId() + " found");
704700 }
705701 if (path.contains(parent)) {
706702 path.add(0, parent);
707 Message.verbose("circular dependency found while looking for the path for another one: "
708 + "was looking for " + from + " as a caller of " + path.get(path.size() - 1));
703 Message.verbose(
704 "circular dependency found while looking for the path for another one: was looking for "
705 + from + " as a caller of " + path.get(path.size() - 1));
709706 return path;
710707 }
711708 path.add(0, parent);
718715 /**
719716 * Update data in this node from data of the given node, for the given root module
720717 * configuration.
721 *
718 *
722719 * @param node
723720 * the source node from which data should be copied
724721 * @param rootModuleConf
737734 } else {
738735 // let's copy usage information for the given rootModuleConf, into a separate usage
739736 // object to keep detailed data about where usage comes from
740 IvyNodeUsage mergedUsage = (IvyNodeUsage) mergedUsages.get(node.getId());
737 IvyNodeUsage mergedUsage = mergedUsages.get(node.getId());
741738 if (mergedUsage == null) {
742739 mergedUsage = new IvyNodeUsage(node);
743740 mergedUsages.put(node.getId(), mergedUsage);
750747 updateConfsToFetch(node.confsToFetch);
751748 }
752749
753 private Collection/* <IvyNodeUsage> */getAllUsages() {
754 Collection usages = new ArrayList();
750 private Collection<IvyNodeUsage> getAllUsages() {
751 Collection<IvyNodeUsage> usages = new ArrayList<>();
755752 usages.add(usage);
756753 usages.addAll(mergedUsages.values());
757754 return usages;
759756
760757 /**
761758 * Returns all the artifacts of this dependency required in all the root module configurations
762 *
763 * @return
759 *
760 * @return array of {@link Artifact}s
764761 */
765762 public Artifact[] getAllArtifacts() {
766 Set ret = new HashSet();
767
768 for (Iterator it = getRootModuleConfigurationsSet().iterator(); it.hasNext();) {
769 String rootModuleConf = (String) it.next();
763 Set<Artifact> ret = new HashSet<>();
764 for (String rootModuleConf : getRootModuleConfigurationsSet()) {
770765 ret.addAll(Arrays.asList(getArtifacts(rootModuleConf)));
771766 }
772 return (Artifact[]) ret.toArray(new Artifact[ret.size()]);
767 return ret.toArray(new Artifact[ret.size()]);
773768 }
774769
775770 /**
776771 * Returns all the artifacts of this dependency required in the root module configurations in
777772 * which the node is not evicted nor blacklisted
778 *
779 * @param artifactFilter
780 * @return
781 */
782 public Artifact[] getSelectedArtifacts(Filter artifactFilter) {
783 Collection ret = new HashSet();
784 for (Iterator it = getRootModuleConfigurationsSet().iterator(); it.hasNext();) {
785 String rootModuleConf = (String) it.next();
773 *
774 * @param artifactFilter Filter
775 * @return array of {@link Artifact}s
776 */
777 public Artifact[] getSelectedArtifacts(Filter<Artifact> artifactFilter) {
778 Collection<Artifact> ret = new HashSet<>();
779 for (String rootModuleConf : getRootModuleConfigurationsSet()) {
786780 if (!isEvicted(rootModuleConf) && !isBlacklisted(rootModuleConf)) {
787781 ret.addAll(Arrays.asList(getArtifacts(rootModuleConf)));
788782 }
789783 }
790784 ret = FilterHelper.filter(ret, artifactFilter);
791 return (Artifact[]) ret.toArray(new Artifact[ret.size()]);
785 return ret.toArray(new Artifact[ret.size()]);
792786 }
793787
794788 /**
795789 * Returns the artifacts of this dependency required in the configurations themselves required
796790 * in the given root module configuration
797 *
798 * @param rootModuleConf
799 * @return
791 *
792 * @param rootModuleConf String
793 * @return array of {@link Artifact}s
800794 */
801795 public Artifact[] getArtifacts(String rootModuleConf) {
802796 // first we look for the dependency configurations required
809803 if (md == null) {
810804 throw new IllegalStateException(
811805 "impossible to get artifacts when data has not been loaded. IvyNode = "
812 + this.toString());
813 }
814
815 Set artifacts = new HashSet(); // the set we fill before returning
806 + this);
807 }
808
809 Set<Artifact> artifacts = new HashSet<>(); // the set we fill before returning
816810
817811 // we check if we have dependencyArtifacts includes description for this rootModuleConf
818 Set dependencyArtifacts = usage.getDependencyArtifactsSet(rootModuleConf);
812 Set<DependencyArtifactDescriptor> dependencyArtifacts = usage
813 .getDependencyArtifactsSet(rootModuleConf);
819814
820815 if (md.isDefault() && dependencyArtifacts != null && !dependencyArtifacts.isEmpty()) {
821816 addArtifactsFromOwnUsage(artifacts, dependencyArtifacts);
822817 addArtifactsFromMergedUsage(rootModuleConf, artifacts);
823818 } else {
824 Set includes = new LinkedHashSet();
819 Set<IncludeRule> includes = new LinkedHashSet<>();
825820 addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf));
826 for (Iterator iterator = mergedUsages.values().iterator(); iterator.hasNext();) {
827 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
821 for (IvyNodeUsage usage : mergedUsages.values()) {
828822 addAllIfNotNull(includes, usage.getDependencyIncludesSet(rootModuleConf));
829823 }
830824
831825 if ((dependencyArtifacts == null || dependencyArtifacts.isEmpty())
832 && (includes.isEmpty())) {
826 && includes.isEmpty()) {
833827 // no artifacts / includes: we get all artifacts as defined by the descriptor
834 for (int i = 0; i < confs.length; i++) {
835 artifacts.addAll(Arrays.asList(md.getArtifacts(confs[i])));
828 for (String conf : confs) {
829 artifacts.addAll(Arrays.asList(md.getArtifacts(conf)));
836830 }
837831 } else {
838 // we have to get only artifacts listed as "includes"
839
832 // we have to get only artifacts listed as "includes";
840833 // first we get all artifacts as defined by the module descriptor
841834 // and classify them by artifact id
842 Map allArtifacts = new HashMap();
843 for (int i = 0; i < confs.length; i++) {
844 Artifact[] arts = md.getArtifacts(confs[i]);
845 for (int j = 0; j < arts.length; j++) {
846 allArtifacts.put(arts[j].getId().getArtifactId(), arts[j]);
835 Map<ArtifactId, Artifact> allArtifacts = new HashMap<>();
836 for (String conf : confs) {
837 for (Artifact art : md.getArtifacts(conf)) {
838 allArtifacts.put(art.getId().getArtifactId(), art);
847839 }
848840 }
849841
854846 addArtifactsFromMergedUsage(rootModuleConf, artifacts);
855847
856848 // and now we filter according to include rules
857 for (Iterator it = includes.iterator(); it.hasNext();) {
858 IncludeRule dad = (IncludeRule) it.next();
859 Collection arts = findArtifactsMatching(dad, allArtifacts);
849 Iterator<IncludeRule> it = includes.iterator();
850 while (it.hasNext()) {
851 IncludeRule dad = it.next();
852 Collection<Artifact> arts = findArtifactsMatching(dad, allArtifacts);
860853 if (arts.isEmpty()) {
861854 Message.error("a required artifact is not listed by module descriptor: "
862855 + dad.getId());
871864 }
872865 }
873866
874 // now excludes artifacts that aren't accepted by any caller
875 for (Iterator iter = artifacts.iterator(); iter.hasNext();) {
876 Artifact artifact = (Artifact) iter.next();
867 // now exclude artifacts that aren't accepted by any caller
868 Iterator<Artifact> iter = artifacts.iterator();
869 while (iter.hasNext()) {
870 Artifact artifact = iter.next();
877871 boolean excluded = callers.doesCallersExclude(rootModuleConf, artifact);
878872 if (excluded) {
879873 Message.debug(this + " in " + rootModuleConf + ": excluding " + artifact);
880874 iter.remove();
881875 }
882876 }
883 return (Artifact[]) artifacts.toArray(new Artifact[artifacts.size()]);
884 }
885
886 private void addArtifactsFromOwnUsage(Set artifacts, Set dependencyArtifacts) {
887 for (Iterator it = dependencyArtifacts.iterator(); it.hasNext();) {
888 DependencyArtifactDescriptor dad = (DependencyArtifactDescriptor) it.next();
877 return artifacts.toArray(new Artifact[artifacts.size()]);
878 }
879
880 private void addArtifactsFromOwnUsage(Set<Artifact> artifacts,
881 Set<DependencyArtifactDescriptor> dependencyArtifacts) {
882 for (DependencyArtifactDescriptor dad : dependencyArtifacts) {
889883 artifacts.add(new MDArtifact(md, dad.getName(), dad.getType(), dad.getExt(), dad
890884 .getUrl(), dad.getQualifiedExtraAttributes()));
891885 }
892886 }
893887
894 private void addArtifactsFromMergedUsage(String rootModuleConf, Set artifacts) {
895 for (Iterator iterator = mergedUsages.values().iterator(); iterator.hasNext();) {
896 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
897 Set mergedDependencyArtifacts = usage.getDependencyArtifactsSet(rootModuleConf);
888 private void addArtifactsFromMergedUsage(String rootModuleConf, Set<Artifact> artifacts) {
889 for (IvyNodeUsage usage : mergedUsages.values()) {
890 Set<DependencyArtifactDescriptor> mergedDependencyArtifacts = usage
891 .getDependencyArtifactsSet(rootModuleConf);
898892 if (mergedDependencyArtifacts != null) {
899 for (Iterator it = mergedDependencyArtifacts.iterator(); it.hasNext();) {
900 DependencyArtifactDescriptor dad = (DependencyArtifactDescriptor) it.next();
901 Map extraAttributes = new HashMap(dad.getQualifiedExtraAttributes());
893 for (DependencyArtifactDescriptor dad : mergedDependencyArtifacts) {
894 Map<String, String> extraAttributes = new HashMap<>(
895 dad.getQualifiedExtraAttributes());
902896 MDArtifact artifact = new MDArtifact(md, dad.getName(), dad.getType(),
903897 dad.getExt(), dad.getUrl(), extraAttributes);
904898
913907 }
914908 }
915909
916 private static Collection findArtifactsMatching(IncludeRule rule, Map allArtifacts) {
917 Collection ret = new ArrayList();
918 for (Iterator iter = allArtifacts.keySet().iterator(); iter.hasNext();) {
919 ArtifactId aid = (ArtifactId) iter.next();
920 if (MatcherHelper.matches(rule.getMatcher(), rule.getId(), aid)) {
921 ret.add(allArtifacts.get(aid));
910 private static Collection<Artifact> findArtifactsMatching(IncludeRule rule,
911 Map<ArtifactId, Artifact> allArtifacts) {
912 Collection<Artifact> ret = new ArrayList<>();
913 for (Map.Entry<ArtifactId, Artifact> entry : allArtifacts.entrySet()) {
914 if (MatcherHelper.matches(rule.getMatcher(), rule.getId(), entry.getKey())) {
915 ret.add(entry.getValue());
922916 }
923917 }
924918 return ret;
968962 if (md == null) {
969963 throw new IllegalStateException(
970964 "impossible to get conflict manager when data has not been loaded. IvyNode = "
971 + this.toString());
965 + this);
972966 }
973967 ConflictManager cm = md.getConflictManager(mid);
974968 return cm == null ? settings.getConflictManager(mid) : cm;
10081002
10091003 /**
10101004 * Returns the last modified timestamp of the module represented by this Node, or 0 if the last
1011 * modified timestamp is currently unkwown (module not loaded)
1012 *
1005 * modified timestamp is currently unknown (module not loaded)
1006 *
10131007 * @return the last modified timestamp of the module represented by this Node
10141008 */
10151009 public long getLastModified() {
10221016 public ModuleRevisionId getResolvedId() {
10231017 if (md != null && md.getResolvedModuleRevisionId().getRevision() != null) {
10241018 return md.getResolvedModuleRevisionId();
1025 } else if (module != null) {
1019 }
1020 if (module != null) {
10261021 return module.getId();
1027 } else {
1028 return getId();
1029 }
1022 }
1023 return getId();
10301024 }
10311025
10321026 /**
10411035 // /////////////////////////////////////////////////////////////////////////////
10421036
10431037 boolean canExclude(String rootModuleConf) {
1044 Caller[] callers = getCallers(rootModuleConf);
1045 for (int i = 0; i < callers.length; i++) {
1046 if (callers[i].canExclude()) {
1038 for (Caller caller : getCallers(rootModuleConf)) {
1039 if (caller.canExclude()) {
10471040 return true;
10481041 }
10491042 }
10581051 return callers.getCallers(rootModuleConf);
10591052 }
10601053
1061 public Collection getAllCallersModuleIds() {
1054 public Collection<ModuleId> getAllCallersModuleIds() {
10621055 return callers.getAllCallersModuleIds();
10631056 }
10641057
10811074 }
10821075 }
10831076
1084 public boolean doesCallersExclude(String rootModuleConf, Artifact artifact, Stack callersStack) {
1077 public boolean doesCallersExclude(String rootModuleConf, Artifact artifact,
1078 Deque<IvyNode> callersStack) {
10851079 return callers.doesCallersExclude(rootModuleConf, artifact, callersStack);
10861080 }
10871081
1088 private ModuleRevisionId[] toMrids(Collection path, IvyNode depNode) {
1082 @Deprecated
1083 public boolean doesCallersExclude(String rootModuleConf, Artifact artifact,
1084 Stack<ModuleRevisionId> callersStack) {
1085 Deque<IvyNode> callersDeque = new ArrayDeque<>();
1086 for (ModuleRevisionId mrid : callersStack) {
1087 for (Caller caller : getCallers(rootModuleConf)) {
1088 if (caller.getModuleRevisionId().equals(mrid)) {
1089 callersDeque.add(data.getNode(mrid));
1090 }
1091 }
1092 }
1093 return callers.doesCallersExclude(rootModuleConf, artifact, callersDeque);
1094 }
1095
1096 private ModuleRevisionId[] toMrids(Collection<IvyNode> path, IvyNode depNode) {
10891097 ModuleRevisionId[] ret = new ModuleRevisionId[path.size() + 1];
10901098 int i = 0;
1091 for (Iterator iter = path.iterator(); iter.hasNext(); i++) {
1092 IvyNode node = (IvyNode) iter.next();
1093 ret[i] = node.getId();
1099 for (IvyNode node : path) {
1100 ret[i++] = node.getId();
10941101 }
10951102 ret[ret.length - 1] = depNode.getId();
10961103 return ret;
11001107 // EVICTION MANAGEMENT
11011108 // /////////////////////////////////////////////////////////////////////////////
11021109
1103 /** A copy of the set of resolved nodes (real nodes) */
1104 public Set getResolvedNodes(ModuleId moduleId, String rootModuleConf) {
1110 /**
1111 * A copy of the set of resolved nodes (real nodes)
1112 *
1113 * @param moduleId ditto
1114 * @param rootModuleConf String
1115 * @return Set&lt;IvyNode&gt;
1116 */
1117 public Set<IvyNode> getResolvedNodes(ModuleId moduleId, String rootModuleConf) {
11051118 return eviction.getResolvedNodes(moduleId, rootModuleConf);
11061119 }
11071120
1108 public Collection getResolvedRevisions(ModuleId moduleId, String rootModuleConf) {
1121 public Collection<ModuleRevisionId> getResolvedRevisions(ModuleId moduleId,
1122 String rootModuleConf) {
11091123 return eviction.getResolvedRevisions(moduleId, rootModuleConf);
11101124 }
11111125
11151129
11161130 // bug 105: update selected data with evicted one
11171131 if (evictionData.getSelected() != null) {
1118 for (Iterator iter = evictionData.getSelected().iterator(); iter.hasNext();) {
1119 IvyNode selected = (IvyNode) iter.next();
1132 for (IvyNode selected : evictionData.getSelected()) {
11201133 selected.updateDataFrom(this, rootModuleConf, false);
11211134 }
11221135 }
11231136 }
11241137
1125 public Collection getAllEvictingConflictManagers() {
1138 public Collection<ConflictManager> getAllEvictingConflictManagers() {
11261139 return eviction.getAllEvictingConflictManagers();
11271140 }
11281141
1129 public Collection getAllEvictingNodes() {
1142 public Collection<IvyNode> getAllEvictingNodes() {
11301143 return eviction.getAllEvictingNodes();
11311144 }
11321145
1133 public Collection/* <String> */getAllEvictingNodesDetails() {
1146 public Collection<String> getAllEvictingNodesDetails() {
11341147 return eviction.getAllEvictingNodesDetails();
11351148 }
11361149
11421155 return eviction.getEvictedData(rootModuleConf);
11431156 }
11441157
1145 public Collection getEvictedNodes(ModuleId mid, String rootModuleConf) {
1158 public Collection<IvyNode> getEvictedNodes(ModuleId mid, String rootModuleConf) {
11461159 return eviction.getEvictedNodes(mid, rootModuleConf);
11471160 }
11481161
1149 public Collection getEvictedRevisions(ModuleId mid, String rootModuleConf) {
1162 public Collection<ModuleRevisionId> getEvictedRevisions(ModuleId mid, String rootModuleConf) {
11501163 return eviction.getEvictedRevisions(mid, rootModuleConf);
11511164 }
11521165
11631176 }
11641177
11651178 public void markEvicted(String rootModuleConf, IvyNode node, ConflictManager conflictManager,
1166 Collection resolved) {
1179 Collection<IvyNode> resolved) {
11671180 EvictionData evictionData = new EvictionData(rootModuleConf, node, conflictManager,
11681181 resolved);
11691182 markEvicted(evictionData);
11701183 }
11711184
1172 public void setEvictedNodes(ModuleId moduleId, String rootModuleConf, Collection evicted) {
1185 public void setEvictedNodes(ModuleId moduleId, String rootModuleConf,
1186 Collection<IvyNode> evicted) {
11731187 eviction.setEvictedNodes(moduleId, rootModuleConf, evicted);
11741188 }
11751189
1176 public void setResolvedNodes(ModuleId moduleId, String rootModuleConf, Collection resolved) {
1190 public void setResolvedNodes(ModuleId moduleId, String rootModuleConf,
1191 Collection<IvyNode> resolved) {
11771192 eviction.setResolvedNodes(moduleId, rootModuleConf, resolved);
11781193 }
11791194
1195 @Override
11801196 public String toString() {
11811197 return getResolvedId().toString();
11821198 }
11831199
1200 @Override
11841201 public boolean equals(Object obj) {
11851202 if (!(obj instanceof IvyNode)) {
11861203 return false;
11891206 return node.getId().equals(getId());
11901207 }
11911208
1192 public int compareTo(Object obj) {
1193 IvyNode that = (IvyNode) obj;
1209 public int compareTo(IvyNode that) {
11941210 return this.getModuleId().compareTo(that.getModuleId());
11951211 }
11961212
1213 @Override
11971214 public int hashCode() {
11981215 return getId().hashCode();
11991216 }
12011218 /**
12021219 * Returns a collection of Nodes in conflict for which conflict has been detected but conflict
12031220 * resolution hasn't been done yet
1204 *
1205 * @param rootModuleConf
1221 *
1222 * @param rootModuleConf ditto
12061223 * @param mid
12071224 * the module id for which pending conflicts should be found
12081225 * @return a Collection of IvyNode in pending conflict
12091226 */
1210 public Collection getPendingConflicts(String rootModuleConf, ModuleId mid) {
1227 public Collection<IvyNode> getPendingConflicts(String rootModuleConf, ModuleId mid) {
12111228 return eviction.getPendingConflicts(rootModuleConf, mid);
12121229 }
12131230
1214 public void setPendingConflicts(ModuleId moduleId, String rootModuleConf, Collection conflicts) {
1231 public void setPendingConflicts(ModuleId moduleId, String rootModuleConf,
1232 Collection<IvyNode> conflicts) {
12151233 eviction.setPendingConflicts(moduleId, rootModuleConf, conflicts);
12161234 }
12171235
12271245 * implementation which use a best effort strategy to find compatible dependency set, like
12281246 * {@link LatestCompatibleConflictManager}
12291247 * </p>
1230 *
1231 * @param rootModuleConf
1248 *
1249 * @param bdata
12321250 * the root module configuration in which the node should be blacklisted
12331251 */
12341252 public void blacklist(IvyNodeBlacklist bdata) {
12381256 Message.verbose("BLACKLISTING " + bdata);
12391257 }
12401258
1241 Stack callerStack = new Stack();
1259 Stack<IvyNode> callerStack = new Stack<>();
12421260 callerStack.push(this);
12431261 clearEvictionDataInAllCallers(bdata.getRootModuleConf(), callerStack);
12441262
12461264 data.blacklist(this);
12471265 }
12481266
1249 private void clearEvictionDataInAllCallers(String rootModuleConf,
1250 Stack/* <IvyNode> */callerStack) {
1251 IvyNode node = (IvyNode) callerStack.peek();
1252 Caller[] callers = node.getCallers(rootModuleConf);
1253 for (int i = 0; i < callers.length; i++) {
1254 IvyNode callerNode = findNode(callers[i].getModuleRevisionId());
1267 private void clearEvictionDataInAllCallers(String rootModuleConf, Stack<IvyNode> callerStack) {
1268 for (Caller caller : callerStack.peek().getCallers(rootModuleConf)) {
1269 IvyNode callerNode = findNode(caller.getModuleRevisionId());
12551270 if (callerNode != null) {
12561271 callerNode.eviction = new IvyNodeEviction(callerNode);
12571272 if (!callerStack.contains(callerNode)) {
12681283 * <p>
12691284 * A blacklisted node should be considered as if it doesn't even exist on the repository.
12701285 * </p>
1271 *
1286 *
12721287 * @param rootModuleConf
12731288 * the root module conf for which we'd like to know if the node is blacklisted
1274 *
1289 *
12751290 * @return true if this node is blacklisted int he given root module conf, false otherwise
1276 * @see #blacklist(String)
1291 * @see #blacklist(IvyNodeBlacklist)
12771292 */
12781293 public boolean isBlacklisted(String rootModuleConf) {
12791294 return usage.isBlacklisted(rootModuleConf);
12811296
12821297 /**
12831298 * Indicates if this node has been blacklisted in all root module configurations.
1284 *
1299 *
12851300 * @return true if this node is blacklisted in all root module configurations, false otherwise
1286 * @see #blacklist(String)
1301 * @see #blacklist(IvyNodeBlacklist)
12871302 */
12881303 public boolean isCompletelyBlacklisted() {
12891304 if (isRoot()) {
12901305 return false;
12911306 }
1292 String[] rootModuleConfigurations = getRootModuleConfigurations();
1293 for (int i = 0; i < rootModuleConfigurations.length; i++) {
1294 if (!isBlacklisted(rootModuleConfigurations[i])) {
1307 for (String rootModuleConfiguration : getRootModuleConfigurations()) {
1308 if (!isBlacklisted(rootModuleConfiguration)) {
12951309 return false;
12961310 }
12971311 }
13011315 /**
13021316 * Returns the blacklist data of this node in the given root module conf, or <code>null</code>
13031317 * if this node is not blacklisted in this root module conf.
1304 *
1318 *
13051319 * @param rootModuleConf
13061320 * the root module configuration to consider
13071321 * @return the blacklist data if any
13221336 * given root module conf which has a dependency descriptor with transitive == true, then it
13231337 * returns true. Otherwise it returns false.
13241338 * </p>
1325 *
1339 *
13261340 * @param rootModuleConf
13271341 * the root module configuration to consider
13281342 * @return true if there is any merged usage with transitive dd, false otherwise.
13311345 if (mergedUsages == null) {
13321346 return false;
13331347 }
1334 for (Iterator iterator = mergedUsages.values().iterator(); iterator.hasNext();) {
1335 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
1348 for (IvyNodeUsage usage : mergedUsages.values()) {
13361349 if (usage.hasTransitiveDepender(rootModuleConf)) {
13371350 return true;
13381351 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.core.resolve;
1818
19 import java.util.ArrayDeque;
1920 import java.util.Arrays;
2021 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.Deque;
2124 import java.util.HashMap;
2225 import java.util.HashSet;
23 import java.util.Iterator;
2426 import java.util.Map;
2527 import java.util.Set;
26 import java.util.Stack;
2728
2829 import org.apache.ivy.core.module.descriptor.Artifact;
2930 import org.apache.ivy.core.module.descriptor.Configuration;
31 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
3032 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3133 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3234 import org.apache.ivy.core.module.id.ModuleId;
3840
3941 private ModuleRevisionId mrid;
4042
41 private Map confs = new HashMap(); // Map (String callerConf -> String[] dependencyConfs)
43 // callerConf -> dependencyConfs
44 private Map<String, String[]> confs = new HashMap<>();
4245
4346 private DependencyDescriptor dd;
4447
6063 if (conf != null) {
6164 String[] confExtends = conf.getExtends();
6265 if (confExtends != null) {
63 for (int i = 0; i < confExtends.length; i++) {
64 addConfiguration(confExtends[i], dependencyConfs);
66 for (String confExtend : confExtends) {
67 addConfiguration(confExtend, dependencyConfs);
6568 }
6669 }
6770 }
6871 }
6972
7073 private void updateConfs(String callerConf, String[] dependencyConfs) {
71 String[] prevDepConfs = (String[]) confs.get(callerConf);
74 String[] prevDepConfs = confs.get(callerConf);
7275 if (prevDepConfs != null) {
73 Set newDepConfs = new HashSet(Arrays.asList(prevDepConfs));
76 Set<String> newDepConfs = new HashSet<>(Arrays.asList(prevDepConfs));
7477 newDepConfs.addAll(Arrays.asList(dependencyConfs));
7578 confs.put(callerConf, newDepConfs.toArray(new String[newDepConfs.size()]));
7679 } else {
7982 }
8083
8184 public String[] getCallerConfigurations() {
82 return (String[]) confs.keySet().toArray(new String[confs.keySet().size()]);
85 return confs.keySet().toArray(new String[confs.keySet().size()]);
8386 }
8487
8588 public ModuleRevisionId getModuleRevisionId() {
8689 return mrid;
8790 }
8891
92 @Override
8993 public boolean equals(Object obj) {
9094 if (!(obj instanceof Caller)) {
9195 return false;
9498 return other.confs.equals(confs) && mrid.equals(other.mrid);
9599 }
96100
101 @Override
97102 public int hashCode() {
98103 // CheckStyle:MagicNumber| OFF
99104 int hash = 31;
103108 return hash;
104109 }
105110
111 @Override
106112 public String toString() {
107113 return mrid.toString();
108114 }
109115
116 @Deprecated
110117 public ModuleRevisionId getAskedDependencyId(ResolveData resolveData) {
118 return getAskedDependencyId();
119 }
120
121 public ModuleRevisionId getAskedDependencyId() {
111122 return dd.getDependencyRevisionId();
112123 }
113124
132143 }
133144 }
134145
135 // Map (String rootModuleConf -> Map (ModuleRevisionId -> Caller)): key in second map is used to
136 // easily get a caller by its mrid
137 private Map callersByRootConf = new HashMap();
146 // key in second map is used to easily get a caller by its mrid
147 private Map<String, Map<ModuleRevisionId, Caller>> callersByRootConf = new HashMap<>();
138148
139149 // this map contains all the module ids calling this one (including transitively) as keys.
140150 // the mapped nodes (values) correspond to a direct caller from which the transitive caller
141151 // comes
142
143 private Map allCallers = new HashMap(); // Map (ModuleId -> IvyNode)
152 private Map<ModuleId, IvyNode> allCallers = new HashMap<>();
144153
145154 private IvyNode node;
146155
149158 }
150159
151160 /**
152 * @param rootModuleConf
153 * @param mrid
154 * @param callerConf
161 * @param rootModuleConf ditto
162 * @param callerNode IvyNode
163 * @param callerConf ditto
164 * @param requestedConf ditto
155165 * @param dependencyConfs
156166 * '*' must have been resolved
157167 * @param dd
165175 throw new IllegalArgumentException("a module is not authorized to depend on itself: "
166176 + node.getId());
167177 }
168 Map callers = (Map) callersByRootConf.get(rootModuleConf);
178 Map<ModuleRevisionId, Caller> callers = callersByRootConf.get(rootModuleConf);
169179 if (callers == null) {
170 callers = new HashMap();
180 callers = new HashMap<>();
171181 callersByRootConf.put(rootModuleConf, callers);
172182 }
173 Caller caller = (Caller) callers.get(mrid);
183 Caller caller = callers.get(mrid);
174184 if (caller == null) {
175185 caller = new Caller(md, mrid, dd, callerNode.canExclude(rootModuleConf));
176186 callers.put(mrid, caller);
178188 caller.addConfiguration(requestedConf, dependencyConfs);
179189
180190 IvyNode parent = callerNode.getRealNode();
181 for (Iterator iter = parent.getAllCallersModuleIds().iterator(); iter.hasNext();) {
182 ModuleId mid = (ModuleId) iter.next();
191 for (ModuleId mid : parent.getAllCallersModuleIds()) {
183192 allCallers.put(mid, parent);
184193 }
185194 allCallers.put(mrid.getModuleId(), callerNode);
187196
188197 void removeCaller(String rootModuleConf, ModuleRevisionId callerMrid) {
189198 allCallers.remove(callerMrid.getModuleId());
190 Map callers = (Map) callersByRootConf.get(rootModuleConf);
199 Map<ModuleRevisionId, Caller> callers = callersByRootConf.get(rootModuleConf);
191200 if (callers != null) {
192201 callers.remove(callerMrid);
193202 }
194203 }
195204
196205 public Caller[] getCallers(String rootModuleConf) {
197 Map callers = (Map) callersByRootConf.get(rootModuleConf);
206 Map<ModuleRevisionId, Caller> callers = callersByRootConf.get(rootModuleConf);
198207 if (callers == null) {
199208 return new Caller[0];
200209 }
201 return (Caller[]) callers.values().toArray(new Caller[callers.values().size()]);
210 return callers.values().toArray(new Caller[callers.values().size()]);
211 }
212
213 private Set<Caller> getCallersByMrid(String rootModuleConf, ModuleRevisionId mrid) {
214 Map<ModuleRevisionId, Caller> callers = callersByRootConf.get(rootModuleConf);
215 if (callers == null) {
216 return Collections.emptySet();
217 }
218
219 Set<Caller> mridCallers = new HashSet<>();
220 for (Caller caller : callers.values()) {
221 if (caller.getAskedDependencyId().equals(mrid)) {
222 mridCallers.add(caller);
223 }
224 }
225 return mridCallers;
202226 }
203227
204228 public Caller[] getAllCallers() {
205 Set all = new HashSet();
206 for (Iterator iter = callersByRootConf.values().iterator(); iter.hasNext();) {
207 Map callers = (Map) iter.next();
229 Set<Caller> all = new HashSet<>();
230 for (Map<ModuleRevisionId, Caller> callers : callersByRootConf.values()) {
208231 all.addAll(callers.values());
209232 }
210 return (Caller[]) all.toArray(new Caller[all.size()]);
233 return all.toArray(new Caller[all.size()]);
211234 }
212235
213236 public Caller[] getAllRealCallers() {
214 Set all = new HashSet();
215 for (Iterator iter = callersByRootConf.values().iterator(); iter.hasNext();) {
216 Map callers = (Map) iter.next();
217 for (Iterator iterator = callers.values().iterator(); iterator.hasNext();) {
218 Caller c = (Caller) iterator.next();
237 Set<Caller> all = new HashSet<>();
238 for (Map<ModuleRevisionId, Caller> callers : callersByRootConf.values()) {
239 for (Caller c : callers.values()) {
219240 if (c.isRealCaller()) {
220241 all.add(c);
221242 }
222243 }
223244 }
224 return (Caller[]) all.toArray(new Caller[all.size()]);
225 }
226
227 public Collection getAllCallersModuleIds() {
245 return all.toArray(new Caller[all.size()]);
246 }
247
248 public Collection<ModuleId> getAllCallersModuleIds() {
228249 return allCallers.keySet();
229250 }
230251
231252 void updateFrom(IvyNodeCallers callers, String rootModuleConf, boolean real) {
232 Map nodecallers = (Map) callers.callersByRootConf.get(rootModuleConf);
253 Map<ModuleRevisionId, Caller> nodecallers = callers.callersByRootConf.get(rootModuleConf);
233254 if (nodecallers != null) {
234 Map thiscallers = (Map) callersByRootConf.get(rootModuleConf);
255 Map<ModuleRevisionId, Caller> thiscallers = callersByRootConf.get(rootModuleConf);
235256 if (thiscallers == null) {
236 thiscallers = new HashMap();
257 thiscallers = new HashMap<>();
237258 callersByRootConf.put(rootModuleConf, thiscallers);
238259 }
239 for (Iterator iter = nodecallers.values().iterator(); iter.hasNext();) {
240 Caller caller = (Caller) iter.next();
260 for (Caller caller : nodecallers.values()) {
241261 if (!thiscallers.containsKey(caller.getModuleRevisionId())) {
242262 if (!real) {
243263 caller.setRealCaller(false);
249269 }
250270
251271 public IvyNode getDirectCallerFor(ModuleId from) {
252 return (IvyNode) allCallers.get(from);
272 return allCallers.get(from);
253273 }
254274
255275 /**
256276 * Returns true if ALL callers exclude the given artifact in the given root module conf
257 *
258 * @param rootModuleConf
259 * @param artifact
260 * @return
277 *
278 * @param rootModuleConf ditto
279 * @param artifact Artifact
280 * @return boolean
261281 */
262282 boolean doesCallersExclude(String rootModuleConf, Artifact artifact) {
263 return doesCallersExclude(rootModuleConf, artifact, new Stack());
264 }
265
266 boolean doesCallersExclude(String rootModuleConf, Artifact artifact, Stack callersStack) {
267 callersStack.push(node.getId());
283 return doesCallersExclude(rootModuleConf, artifact, new ArrayDeque<IvyNode>());
284 }
285
286 boolean doesCallersExclude(String rootModuleConf, Artifact artifact,
287 Deque<IvyNode> callersStack) {
288 /* The caller stack is, from bottom to top, the path from the
289 artifact we're considering excluding up towards the
290 root. */
291 callersStack.push(node);
268292 try {
269 Caller[] callers = getCallers(rootModuleConf);
270 if (callers.length == 0) {
293 Set<Caller> callers = getCallersByMrid(rootModuleConf, node.getId());
294 if (callers.isEmpty()) {
271295 return false;
272296 }
273 boolean allUnconclusive = true;
274 for (int i = 0; i < callers.length; i++) {
275 if (!callers[i].canExclude()) {
297 boolean allInconclusive = true;
298 String[] moduleConfs = new String[] {rootModuleConf};
299 callers: for (Caller caller : callers) {
300 /* Each ancestor of this artifact (called "descendant", here, since it's
301 a descendant relative to this.node) might itself have been excluded by
302 an older ancestor (this.node); if it is, then it is as if artifact
303 itself were excluded in this path. */
304 for (IvyNode descendant : callersStack) {
305 if (node.directlyExcludes(node.getDescriptor(), moduleConfs,
306 caller.getDependencyDescriptor(),
307 DefaultArtifact.newIvyArtifact(descendant.getId(), null))) {
308 allInconclusive = false;
309 continue callers;
310 }
311 }
312 if (!caller.canExclude()) {
276313 return false;
277314 }
278 ModuleDescriptor md = callers[i].getModuleDescriptor();
279 Boolean doesExclude = node.doesExclude(md, rootModuleConf,
280 callers[i].getCallerConfigurations(), callers[i].getDependencyDescriptor(),
281 artifact, callersStack);
315 Boolean doesExclude = node.doesExclude(caller.getModuleDescriptor(), rootModuleConf,
316 caller.getCallerConfigurations(), caller.getDependencyDescriptor(),
317 artifact, callersStack);
282318 if (doesExclude != null) {
283 if (!doesExclude.booleanValue()) {
319 if (!doesExclude) {
284320 return false;
285321 }
286 allUnconclusive = false;
287 }
288 }
289 return allUnconclusive ? false : true;
322 allInconclusive = false;
323 }
324 }
325 return !allInconclusive;
290326 } finally {
291327 callersStack.pop();
292328 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4545 /**
4646 * Can be null in case of transitive eviction.
4747 */
48 private Collection selected; // Collection(IvyNode)
48 private Collection<IvyNode> selected;
4949
5050 private String rootModuleConf;
5151
5353
5454 /**
5555 * Creates a new object containing the eviction data of an {@link IvyNode}.
56 *
56 *
5757 * @param rootModuleConf
5858 * the root module configuration
5959 * @param parent
6666 * <tt>null</tt> in case of transitive eviction)
6767 */
6868 public EvictionData(String rootModuleConf, IvyNode parent, ConflictManager conflictManager,
69 Collection selected) {
69 Collection<IvyNode> selected) {
7070 this(rootModuleConf, parent, conflictManager, selected, null);
7171 }
7272
7373 /**
7474 * Creates a new object containing the eviction data of an {@link IvyNode}.
75 *
75 *
7676 * @param rootModuleConf
7777 * the root module configuration
7878 * @param parent
8787 * a String detailing the reason why the node was evicted
8888 */
8989 public EvictionData(String rootModuleConf, IvyNode parent, ConflictManager conflictManager,
90 Collection selected, String detail) {
90 Collection<IvyNode> selected, String detail) {
9191 this.rootModuleConf = rootModuleConf;
9292 this.parent = parent;
9393 this.conflictManager = conflictManager;
9595 this.detail = detail;
9696 }
9797
98 @Override
9899 public String toString() {
99100 if (selected != null) {
100101 return selected + " in " + parent + (detail == null ? "" : " " + detail) + " ("
112113 return parent;
113114 }
114115
115 public Collection getSelected() {
116 public Collection<IvyNode> getSelected() {
116117 return selected;
117118 }
118119
153154 return moduleId;
154155 }
155156
157 @Override
156158 public boolean equals(Object obj) {
157 if (!(obj instanceof ModuleIdConf)) {
158 return false;
159 }
160 return getModuleId().equals(((ModuleIdConf) obj).getModuleId())
159 return obj instanceof ModuleIdConf
160 && getModuleId().equals(((ModuleIdConf) obj).getModuleId())
161161 && getConf().equals(((ModuleIdConf) obj).getConf());
162162 }
163163
164 @Override
164165 public int hashCode() {
165166 // CheckStyle:MagicNumber| OFF
166167 int hash = 33;
173174
174175 private IvyNode node;
175176
176 private Map selectedDeps = new HashMap(); // Map (ModuleIdConf -> Set(Node)) // map indicating
177
178 // for each dependency which node has been selected
179
180 private Map pendingConflicts = new HashMap(); // Map (ModuleIdConf -> Set(Node)) // map
181
182 // indicating for each dependency which nodes
183 // are in pending conflict (conflict detected
184 // but not yet resolved)
185
186 private Map evictedDeps = new HashMap(); // Map (ModuleIdConf -> Set(Node)) // map indicating
187
188 // for each dependency which node has been evicted
189
190 private Map evictedRevs = new HashMap(); // Map (ModuleIdConf -> Set(ModuleRevisionId)) //
191
192 // map indicating for each dependency which revision
193 // has been evicted
194
195 private Map evicted = new HashMap(); // Map (root module conf -> EvictionData) // indicates
196
197 // if the node is evicted in each root module conf
177 // map indicating for each dependency which node has been selected
178 private Map<ModuleIdConf, Set<IvyNode>> selectedDeps = new HashMap<>();
179
180 // map indicating for each dependency which nodes are in pending conflict (conflict detected but
181 // not yet resolved)
182 private Map<ModuleIdConf, Set<IvyNode>> pendingConflicts = new HashMap<>();
183
184 // map indicating for each dependency which node has been evicted
185 private Map<ModuleIdConf, Set<IvyNode>> evictedDeps = new HashMap<>();
186
187 // map indicating for each dependency which revision has been evicted
188 private Map<ModuleIdConf, Collection<ModuleRevisionId>> evictedRevs = new HashMap<>();
189
190 // indicates if the node is evicted in each root module conf
191 private Map<String, EvictionData> evicted = new HashMap<>();
198192
199193 public IvyNodeEviction(IvyNode node) {
200194 if (node == null) {
204198 }
205199
206200 /**
201 * @param mid ModuleId
202 * @param rootModuleConf String
207203 * @return A copy of the set of resolved nodes (real nodes)
208204 */
209 public Set getResolvedNodes(ModuleId mid, String rootModuleConf) {
210 Collection resolved = (Collection) selectedDeps.get(new ModuleIdConf(mid, rootModuleConf));
211 Set ret = new HashSet();
205 public Set<IvyNode> getResolvedNodes(ModuleId mid, String rootModuleConf) {
206 Collection<IvyNode> resolved = selectedDeps.get(new ModuleIdConf(mid, rootModuleConf));
207 Set<IvyNode> ret = new HashSet<>();
212208 if (resolved != null) {
213 for (Iterator iter = resolved.iterator(); iter.hasNext();) {
214 IvyNode node = (IvyNode) iter.next();
209 for (IvyNode node : resolved) {
215210 ret.add(node.getRealNode());
216211 }
217212 }
218213 return ret;
219214 }
220215
221 public Collection getResolvedRevisions(ModuleId mid, String rootModuleConf) {
222 Collection resolved = (Collection) selectedDeps.get(new ModuleIdConf(mid, rootModuleConf));
216 public Collection<ModuleRevisionId> getResolvedRevisions(ModuleId mid, String rootModuleConf) {
217 Collection<IvyNode> resolved = selectedDeps.get(new ModuleIdConf(mid, rootModuleConf));
223218 if (resolved == null) {
224 return new HashSet();
219 return new HashSet<>();
225220 } else {
226 Collection resolvedRevs = new HashSet();
227 for (Iterator iter = resolved.iterator(); iter.hasNext();) {
228 IvyNode node = (IvyNode) iter.next();
221 Collection<ModuleRevisionId> resolvedRevs = new HashSet<>();
222 for (IvyNode node : resolved) {
229223 ModuleRevisionId resolvedId = node.getResolvedId();
230224 resolvedRevs.add(node.getId());
231225 resolvedRevs.add(resolvedId);
241235 }
242236 }
243237
244 public void setResolvedNodes(ModuleId moduleId, String rootModuleConf, Collection resolved) {
238 public void setResolvedNodes(ModuleId moduleId, String rootModuleConf,
239 Collection<IvyNode> resolved) {
245240 ModuleIdConf moduleIdConf = new ModuleIdConf(moduleId, rootModuleConf);
246 selectedDeps.put(moduleIdConf, new HashSet(resolved));
247 }
248
249 public Collection getEvictedNodes(ModuleId mid, String rootModuleConf) {
250 Collection resolved = (Collection) evictedDeps.get(new ModuleIdConf(mid, rootModuleConf));
251 Set ret = new HashSet();
241 selectedDeps.put(moduleIdConf, new HashSet<>(resolved));
242 }
243
244 public Collection<IvyNode> getEvictedNodes(ModuleId mid, String rootModuleConf) {
245 Collection<IvyNode> resolved = evictedDeps.get(new ModuleIdConf(mid, rootModuleConf));
246 Set<IvyNode> ret = new HashSet<>();
252247 if (resolved != null) {
253 for (Iterator iter = resolved.iterator(); iter.hasNext();) {
254 IvyNode node = (IvyNode) iter.next();
248 for (IvyNode node : resolved) {
255249 ret.add(node.getRealNode());
256250 }
257251 }
258252 return ret;
259253 }
260254
261 public Collection getEvictedRevisions(ModuleId mid, String rootModuleConf) {
262 Collection evicted = (Collection) evictedRevs.get(new ModuleIdConf(mid, rootModuleConf));
255 public Collection<ModuleRevisionId> getEvictedRevisions(ModuleId mid, String rootModuleConf) {
256 Collection<ModuleRevisionId> evicted = evictedRevs
257 .get(new ModuleIdConf(mid, rootModuleConf));
263258 if (evicted == null) {
264 return new HashSet();
259 return new HashSet<>();
265260 } else {
266 return new HashSet(evicted);
267 }
268 }
269
270 public void setEvictedNodes(ModuleId moduleId, String rootModuleConf, Collection evicted) {
261 return new HashSet<>(evicted);
262 }
263 }
264
265 public void setEvictedNodes(ModuleId moduleId, String rootModuleConf,
266 Collection<IvyNode> evicted) {
271267 ModuleIdConf moduleIdConf = new ModuleIdConf(moduleId, rootModuleConf);
272 evictedDeps.put(moduleIdConf, new HashSet(evicted));
273 Collection evictedRevs = new HashSet();
274 for (Iterator iter = evicted.iterator(); iter.hasNext();) {
275 IvyNode node = (IvyNode) iter.next();
268 evictedDeps.put(moduleIdConf, new HashSet<>(evicted));
269 Collection<ModuleRevisionId> evictedRevs = new HashSet<>();
270 for (IvyNode node : evicted) {
276271 evictedRevs.add(node.getId());
277272 evictedRevs.add(node.getResolvedId());
278273 }
290285 }
291286 IvyNode root = node.getRoot();
292287 ModuleId moduleId = node.getId().getModuleId();
293 Collection resolvedRevisions = root.getResolvedRevisions(moduleId, rootModuleConf);
288 Collection<ModuleRevisionId> resolvedRevisions = root.getResolvedRevisions(moduleId,
289 rootModuleConf);
294290 return !resolvedRevisions.contains(node.getResolvedId())
295291 || evictedData.isTransitivelyEvicted();
296292 }
300296 if (node.isRoot()) {
301297 return false;
302298 }
303 String[] rootModuleConfigurations = node.getRootModuleConfigurations();
304 for (int i = 0; i < rootModuleConfigurations.length; i++) {
305 if (!isEvicted(rootModuleConfigurations[i])) {
299 for (String rootModuleConfiguration : node.getRootModuleConfigurations()) {
300 if (!isEvicted(rootModuleConfiguration)) {
306301 return false;
307302 }
308303 }
311306
312307 private void cleanEvicted() {
313308 // check if it was evicted by a node that we are now the real node for
314 for (Iterator iter = evicted.keySet().iterator(); iter.hasNext();) {
315 String rootModuleConf = (String) iter.next();
316 EvictionData ed = (EvictionData) evicted.get(rootModuleConf);
317 Collection sel = ed.getSelected();
309 Iterator<String> iter = evicted.keySet().iterator();
310 while (iter.hasNext()) {
311 Collection<IvyNode> sel = evicted.get(iter.next()).getSelected();
318312 if (sel != null) {
319 for (Iterator iterator = sel.iterator(); iterator.hasNext();) {
320 IvyNode n = (IvyNode) iterator.next();
313 for (IvyNode n : sel) {
321314 if (n.getRealNode().equals(node)) {
322315 // yes, we are the real node for a selected one !
323316 // we are no more evicted in this conf !
334327
335328 public EvictionData getEvictedData(String rootModuleConf) {
336329 cleanEvicted();
337 return (EvictionData) evicted.get(rootModuleConf);
330 return evicted.get(rootModuleConf);
338331 }
339332
340333 public String[] getEvictedConfs() {
341334 cleanEvicted();
342 return (String[]) evicted.keySet().toArray(new String[evicted.keySet().size()]);
335 return evicted.keySet().toArray(new String[evicted.keySet().size()]);
343336 }
344337
345338 /**
346339 * Returns null if this node has only be evicted transitively, or the the collection of selected
347340 * nodes if it has been evicted by other selected nodes
348 *
349 * @return
341 *
342 * @return Collection&lt;IvyNode&gt;
350343 */
351 public Collection getAllEvictingNodes() {
352 Collection allEvictingNodes = null;
353 for (Iterator iter = evicted.values().iterator(); iter.hasNext();) {
354 EvictionData ed = (EvictionData) iter.next();
355 Collection selected = ed.getSelected();
344 public Collection<IvyNode> getAllEvictingNodes() {
345 Collection<IvyNode> allEvictingNodes = null;
346 for (EvictionData ed : evicted.values()) {
347 Collection<IvyNode> selected = ed.getSelected();
356348 if (selected != null) {
357349 if (allEvictingNodes == null) {
358 allEvictingNodes = new HashSet();
350 allEvictingNodes = new HashSet<>();
359351 }
360352 allEvictingNodes.addAll(selected);
361353 }
363355 return allEvictingNodes;
364356 }
365357
366 public Collection/* <String> */getAllEvictingNodesDetails() {
367 Collection ret = null;
368 for (Iterator iter = evicted.values().iterator(); iter.hasNext();) {
369 EvictionData ed = (EvictionData) iter.next();
370 Collection selected = ed.getSelected();
358 public Collection<String> getAllEvictingNodesDetails() {
359 Collection<String> ret = null;
360 for (EvictionData ed : evicted.values()) {
361 Collection<IvyNode> selected = ed.getSelected();
371362 if (selected != null) {
372363 if (ret == null) {
373 ret = new HashSet();
364 ret = new HashSet<>();
374365 }
375366 if (selected.size() == 1) {
376367 ret.add(selected.iterator().next()
383374 return ret;
384375 }
385376
386 public Collection getAllEvictingConflictManagers() {
387 Collection ret = new HashSet();
388 for (Iterator iter = evicted.values().iterator(); iter.hasNext();) {
389 EvictionData ed = (EvictionData) iter.next();
377 public Collection<ConflictManager> getAllEvictingConflictManagers() {
378 Collection<ConflictManager> ret = new HashSet<>();
379 for (EvictionData ed : evicted.values()) {
390380 ret.add(ed.getConflictManager());
391381 }
392382 return ret;
396386 * Returns the eviction data for this node if it has been previously evicted in the root, null
397387 * otherwise (if it hasn't been evicted in root) for the given rootModuleConf. Note that this
398388 * method only works if conflict resolution has already be done in all the ancestors.
399 *
400 * @param rootModuleConf
401 * @param ancestor
402 * @return
389 *
390 * @param rootModuleConf ditto
391 * @param ancestor IvyNode
392 * @return EvictionData
403393 */
404394 public EvictionData getEvictionDataInRoot(String rootModuleConf, IvyNode ancestor) {
405 Collection selectedNodes = node.getRoot().getResolvedNodes(node.getModuleId(),
395 Collection<IvyNode> selectedNodes = node.getRoot().getResolvedNodes(node.getModuleId(),
406396 rootModuleConf);
407 for (Iterator iter = selectedNodes.iterator(); iter.hasNext();) {
408 IvyNode node = (IvyNode) iter.next();
397 for (IvyNode node : selectedNodes) {
409398 if (node.getResolvedId().equals(this.node.getResolvedId())) {
410399 // the node is part of the selected ones for the root: no eviction data to return
411400 return null;
417406 node.getModuleId()), selectedNodes);
418407 }
419408
420 public Collection getPendingConflicts(String rootModuleConf, ModuleId mid) {
421 Collection resolved = (Collection) pendingConflicts.get(new ModuleIdConf(mid,
422 rootModuleConf));
423 Set ret = new HashSet();
409 public Collection<IvyNode> getPendingConflicts(String rootModuleConf, ModuleId mid) {
410 Collection<IvyNode> resolved = pendingConflicts.get(new ModuleIdConf(mid, rootModuleConf));
411 Set<IvyNode> ret = new HashSet<>();
424412 if (resolved != null) {
425 for (Iterator iter = resolved.iterator(); iter.hasNext();) {
426 IvyNode node = (IvyNode) iter.next();
413 for (IvyNode node : resolved) {
427414 ret.add(node.getRealNode());
428415 }
429416 }
430417 return ret;
431418 }
432419
433 public void setPendingConflicts(ModuleId moduleId, String rootModuleConf, Collection conflicts) {
420 public void setPendingConflicts(ModuleId moduleId, String rootModuleConf,
421 Collection<IvyNode> conflicts) {
434422 ModuleIdConf moduleIdConf = new ModuleIdConf(moduleId, rootModuleConf);
435 pendingConflicts.put(moduleIdConf, new HashSet(conflicts));
423 pendingConflicts.put(moduleIdConf, new HashSet<>(conflicts));
436424 }
437425
438426 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.util.Collection;
2121 import java.util.HashMap;
2222 import java.util.HashSet;
23 import java.util.Iterator;
2423 import java.util.Map;
2524 import java.util.Set;
2625
26 import org.apache.ivy.core.module.descriptor.DefaultIncludeRule;
2727 import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
2828 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
2929 import org.apache.ivy.core.module.descriptor.IncludeRule;
30 import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
31 import org.apache.ivy.core.module.id.ArtifactId;
32 import org.apache.ivy.core.module.id.ModuleId;
33 import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
34 import org.apache.ivy.plugins.matcher.PatternMatcher;
3035
3136 /**
3237 * Class collecting usage data for an IvyNode.
6368 return node;
6469 }
6570
71 @Override
6672 public boolean equals(Object obj) {
67 if (!(obj instanceof NodeConf)) {
68 return false;
69 }
70 return getNode().equals(((NodeConf) obj).getNode())
71 && getConf().equals(((NodeConf) obj).getConf());
72 }
73
73 return obj instanceof NodeConf && getNode().equals(((NodeConf) obj).getNode()) && getConf().equals(((NodeConf) obj).getConf());
74 }
75
76 @Override
7477 public int hashCode() {
7578 // CheckStyle:MagicNumber| OFF
7679 int hash = 33;
8083 return hash;
8184 }
8285
86 @Override
8387 public String toString() {
8488 return "NodeConf(" + conf + ")";
8589 }
9599 this.dependerConf = dependerConf;
96100 }
97101
102 @Override
98103 public String toString() {
99104 return dd + " [" + dependerConf + "]";
100105 }
101106
107 @Override
102108 public boolean equals(Object obj) {
103109 if (!(obj instanceof Depender)) {
104110 return false;
107113 return other.dd == dd && other.dependerConf.equals(dependerConf);
108114 }
109115
116 @Override
110117 public int hashCode() {
111118 int hash = 33;
112119 hash += dd.hashCode() * 13;
117124
118125 private IvyNode node;
119126
120 // Map (String rootConfName -> Set(String confName))
121127 // used to know which configurations of the dependency are required
122128 // for each root module configuration
123 private Map rootModuleConfs = new HashMap();
124
125 // Map (NodeConf in -> Set(String conf))
126 private Map requiredConfs = new HashMap();
127
128 private Map /* <String, Set<Depender>> */dependers = new HashMap();
129
130 // Map (String rootModuleConf -> IvyNodeBlacklist)
131 private Map blacklisted = new HashMap();
129 // rootConfName -> confNames
130 private Map<String, Set<String>> rootModuleConfs = new HashMap<>();
131
132 private Map<NodeConf, Set<String>> requiredConfs = new HashMap<>();
133
134 private Map<String, Set<Depender>> dependers = new HashMap<>();
135
136 // rootModuleConf -> black list
137 private Map<String, IvyNodeBlacklist> blacklisted = new HashMap<>();
132138
133139 public IvyNodeUsage(IvyNode node) {
134140 this.node = node;
135141 }
136142
137 protected Collection getRequiredConfigurations(IvyNode in, String inConf) {
138 return (Collection) requiredConfs.get(new NodeConf(in, inConf));
139 }
140
141 protected void setRequiredConfs(IvyNode parent, String parentConf, Collection confs) {
142 requiredConfs.put(new NodeConf(parent, parentConf), new HashSet(confs));
143 protected Collection<String> getRequiredConfigurations(IvyNode in, String inConf) {
144 return requiredConfs.get(new NodeConf(in, inConf));
145 }
146
147 protected void setRequiredConfs(IvyNode parent, String parentConf, Collection<String> confs) {
148 requiredConfs.put(new NodeConf(parent, parentConf), new HashSet<>(confs));
143149 }
144150
145151 /**
146152 * Returns the configurations of the dependency required in a given root module configuration.
147 *
148 * @param rootModuleConf
149 * @return
153 *
154 * @param rootModuleConf ditto
155 * @return Set&lt;String&gt;
150156 */
151 protected Set getConfigurations(String rootModuleConf) {
152 return (Set) rootModuleConfs.get(rootModuleConf);
153 }
154
155 protected Set addAndGetConfigurations(String rootModuleConf) {
156 Set depConfs = (Set) rootModuleConfs.get(rootModuleConf);
157 protected Set<String> getConfigurations(String rootModuleConf) {
158 return rootModuleConfs.get(rootModuleConf);
159 }
160
161 protected Set<String> addAndGetConfigurations(String rootModuleConf) {
162 Set<String> depConfs = rootModuleConfs.get(rootModuleConf);
157163 if (depConfs == null) {
158 depConfs = new HashSet();
164 depConfs = new HashSet<>();
159165 rootModuleConfs.put(rootModuleConf, depConfs);
160166 }
161167 return depConfs;
162168 }
163169
164 protected Set /* <String> */getRootModuleConfigurations() {
170 protected Set<String> getRootModuleConfigurations() {
165171 return rootModuleConfs.keySet();
166172 }
167173
168 public void updateDataFrom(Collection/* <IvyNodeUsage> */usages, String rootModuleConf) {
169 for (Iterator iterator = usages.iterator(); iterator.hasNext();) {
170 IvyNodeUsage usage = (IvyNodeUsage) iterator.next();
174 public void updateDataFrom(Collection<IvyNodeUsage> usages, String rootModuleConf) {
175 for (IvyNodeUsage usage : usages) {
171176 updateDataFrom(usage, rootModuleConf);
172177 }
173178 }
183188 updateMapOfSetForKey(usage.dependers, dependers, rootModuleConf);
184189 }
185190
186 private void updateMapOfSet(Map from, Map to) {
187 for (Iterator iter = from.keySet().iterator(); iter.hasNext();) {
188 Object key = iter.next();
191 private <K, V> void updateMapOfSet(Map<K, Set<V>> from, Map<K, Set<V>> to) {
192 for (K key : from.keySet()) {
189193 updateMapOfSetForKey(from, to, key);
190194 }
191195 }
192196
193 private void updateMapOfSetForKey(Map from, Map to, Object key) {
194 Set set = (Set) from.get(key);
197 private <K, V> void updateMapOfSetForKey(Map<K, Set<V>> from, Map<K, Set<V>> to, K key) {
198 Set<V> set = from.get(key);
195199 if (set != null) {
196 Set toupdate = (Set) to.get(key);
200 Set<V> toupdate = to.get(key);
197201 if (toupdate != null) {
198202 toupdate.addAll(set);
199203 } else {
200 to.put(key, new HashSet(set));
201 }
202 }
203 }
204
205 // protected void addDependencyArtifacts(String rootModuleConf,
206 // DependencyArtifactDescriptor[] dependencyArtifacts) {
207 // addObjectsForConf(rootModuleConf, Arrays.asList(dependencyArtifacts),
208 // this.dependencyArtifacts);
209 // }
210 //
211 // protected void addDependencyIncludes(String rootModuleConf, IncludeRule[] rules) {
212 // addObjectsForConf(rootModuleConf, Arrays.asList(rules), dependencyIncludes);
213 // }
214 //
215 private void addObjectsForConf(String rootModuleConf, Object objectToAdd, Map map) {
216 Set set = (Set) map.get(rootModuleConf);
204 to.put(key, new HashSet<>(set));
205 }
206 }
207 }
208
209 private <K, V> void addObjectsForConf(K rootModuleConf, V objectToAdd, Map<K, Set<V>> map) {
210 Set<V> set = map.get(rootModuleConf);
217211 if (set == null) {
218 set = new HashSet();
212 set = new HashSet<>();
219213 map.put(rootModuleConf, set);
220214 }
221215 set.add(objectToAdd);
225219 addObjectsForConf(rootModuleConf, new Depender(dd, parentConf), dependers);
226220 }
227221
228 protected Set getDependencyArtifactsSet(String rootModuleConf) {
229 Collection dependersInConf = (Collection) dependers.get(rootModuleConf);
222 protected Set<DependencyArtifactDescriptor> getDependencyArtifactsSet(String rootModuleConf) {
223 if (node.getDescriptor() instanceof WorkspaceModuleDescriptor) {
224 // for a module in the "workspace" artifacts will be actually declared by the resolver
225 return null;
226 }
227 Collection<Depender> dependersInConf = dependers.get(rootModuleConf);
230228 if (dependersInConf == null) {
231229 return null;
232230 }
233 Set dependencyArtifacts = new HashSet();
234 for (Iterator iterator = dependersInConf.iterator(); iterator.hasNext();) {
235 Depender depender = (Depender) iterator.next();
231 Set<DependencyArtifactDescriptor> dependencyArtifacts = new HashSet<>();
232 for (Depender depender : dependersInConf) {
236233 DependencyArtifactDescriptor[] dads = depender.dd
237234 .getDependencyArtifacts(depender.dependerConf);
238235 dependencyArtifacts.addAll(Arrays.asList(dads));
240237 return dependencyArtifacts;
241238 }
242239
243 protected Set getDependencyIncludesSet(String rootModuleConf) {
244 Collection dependersInConf = (Collection) dependers.get(rootModuleConf);
240 protected Set<IncludeRule> getDependencyIncludesSet(final String rootModuleConf) {
241 final Collection<Depender> dependersInConf = dependers.get(rootModuleConf);
245242 if (dependersInConf == null) {
246243 return null;
247244 }
248 Set dependencyIncludes = new HashSet();
249 for (Iterator iterator = dependersInConf.iterator(); iterator.hasNext();) {
250 Depender depender = (Depender) iterator.next();
251 IncludeRule[] rules = depender.dd.getIncludeRules(depender.dependerConf);
252 if (rules == null || rules.length == 0) {
253 // no include rule in at least one depender -> we must include everything,
254 // and so return no include rule at all
255 return null;
256 }
257 dependencyIncludes.addAll(Arrays.asList(rules));
245 final Set<IncludeRule> dependencyIncludes = new HashSet<>();
246 // true if the depedency descriptor of any of the depender *doesn't* have an explicit
247 // "<artifact>" or an "<include>". false otherwise
248 boolean atLeastOneDependerNeedsAllArtifacts = false;
249 // true if the dependency descriptor of any of the depender either has an explicit "<artifact>"
250 // or an "<include>". false otherwise
251 boolean atLeastOneDependerHasSpecificArtifactSelection = false;
252 for (final Depender depender : dependersInConf) {
253 final DependencyArtifactDescriptor dads[] = depender.dd.getDependencyArtifacts(depender.dd.getModuleConfigurations());
254 final boolean declaresArtifacts = dads != null && dads.length > 0;
255 final IncludeRule[] rules = depender.dd.getIncludeRules(depender.dependerConf);
256 final boolean hasIncludeRule = rules != null && rules.length > 0;
257 if (hasIncludeRule) {
258 dependencyIncludes.addAll(Arrays.asList(rules));
259 }
260 if (declaresArtifacts || hasIncludeRule) {
261 atLeastOneDependerHasSpecificArtifactSelection = true;
262 }
263 if (!hasIncludeRule && !declaresArtifacts) {
264 atLeastOneDependerNeedsAllArtifacts = true;
265 }
266 }
267 // so there's at least one depender D1 which has a specific artifact dependency and at the
268 // same time there's a depender D2 which doesn't have any explicit artifact/includes.
269 // so it is expected that an implicit "include all artifacts" is applied so that dependencies
270 // such as D2 get (all) the artifacts that are published by the dependency's module
271 if (atLeastOneDependerHasSpecificArtifactSelection && atLeastOneDependerNeedsAllArtifacts) {
272 // add a "include all artifacts" rule
273 dependencyIncludes.add(includeAllArtifacts());
258274 }
259275 return dependencyIncludes;
260276 }
272288 * <p>
273289 * A blacklisted node should be considered as if it doesn't even exist on the repository.
274290 * </p>
275 *
291 *
276292 * @param rootModuleConf
277293 * the root module conf for which we'd like to know if the node is blacklisted
278 *
294 *
279295 * @return true if this node is blacklisted int he given root module conf, false otherwise
280 * @see #blacklist(String)
296 * @see #blacklist(IvyNodeBlacklist)
281297 */
282298 protected boolean isBlacklisted(String rootModuleConf) {
283299 return blacklisted.containsKey(rootModuleConf);
286302 /**
287303 * Returns the blacklist data of this node in the given root module conf, or <code>null</code>
288304 * if this node is not blacklisted in this root module conf.
289 *
305 *
290306 * @param rootModuleConf
291307 * the root module configuration to consider
292308 * @return the blacklist data if any
293309 */
294310 protected IvyNodeBlacklist getBlacklistData(String rootModuleConf) {
295 return (IvyNodeBlacklist) blacklisted.get(rootModuleConf);
311 return blacklisted.get(rootModuleConf);
296312 }
297313
298314 protected IvyNode getNode() {
302318 /**
303319 * Indicates if at least one depender has a transitive dependency descriptor for the given root
304320 * module conf.
305 *
321 *
306322 * @param rootModuleConf
307323 * the root module conf to consider
308324 * @return <code>true</code> if at least one depender has a transitive dependency descriptor for
309325 * the given root module conf, <code>false</code> otherwise.
310326 */
311327 public boolean hasTransitiveDepender(String rootModuleConf) {
312 Set/* <Depender> */dependersSet = (Set) dependers.get(rootModuleConf);
328 Set<Depender> dependersSet = dependers.get(rootModuleConf);
313329 if (dependersSet == null) {
314330 return false;
315331 }
316 for (Iterator iterator = dependersSet.iterator(); iterator.hasNext();) {
317 Depender depender = (Depender) iterator.next();
332 for (Depender depender : dependersSet) {
318333 if (depender.dd.isTransitive()) {
319334 return true;
320335 }
322337 return false;
323338 }
324339
340 private static IncludeRule includeAllArtifacts() {
341 final ArtifactId aid = new ArtifactId(
342 new ModuleId(PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION),
343 PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION,
344 PatternMatcher.ANY_EXPRESSION);
345 return new DefaultIncludeRule(aid, ExactPatternMatcher.INSTANCE, null);
346 }
347
348
325349 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.util.LinkedHashMap;
2525 import java.util.List;
2626 import java.util.Map;
27 import java.util.Map.Entry;
2827
2928 import org.apache.ivy.core.event.EventManager;
3029 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3635 public class ResolveData {
3736 private ResolveEngine engine;
3837
39 private Map visitData; // shared map of all visit data: Map (ModuleRevisionId -> VisitData)
38 // shared map of all visit data
39 private Map<ModuleRevisionId, VisitData> visitData;
4040
4141 private ConfigurationResolveReport report;
4242
5454 }
5555
5656 public ResolveData(ResolveEngine engine, ResolveOptions options) {
57 this(engine, options, null, new LinkedHashMap());
57 this(engine, options, null, new LinkedHashMap<ModuleRevisionId, VisitData>());
5858 }
5959
6060 public ResolveData(ResolveEngine engine, ResolveOptions options,
6161 ConfigurationResolveReport report) {
62 this(engine, options, report, new LinkedHashMap());
62 this(engine, options, report, new LinkedHashMap<ModuleRevisionId, VisitData>());
6363 }
6464
6565 public ResolveData(ResolveEngine engine, ResolveOptions options,
66 ConfigurationResolveReport report, Map visitData) {
66 ConfigurationResolveReport report, Map<ModuleRevisionId, VisitData> visitData) {
6767 this.engine = engine;
6868 this.report = report;
6969 this.visitData = visitData;
7979 return visitData == null ? null : visitData.getNode();
8080 }
8181
82 public Collection getNodes() {
83 Collection nodes = new ArrayList();
84 for (Iterator iter = visitData.values().iterator(); iter.hasNext();) {
85 VisitData vdata = (VisitData) iter.next();
82 public Collection<IvyNode> getNodes() {
83 Collection<IvyNode> nodes = new ArrayList<>();
84 for (VisitData vdata : visitData.values()) {
8685 nodes.add(vdata.getNode());
8786 }
8887 return nodes;
8988 }
9089
91 public Collection getNodeIds() {
90 public Collection<ModuleRevisionId> getNodeIds() {
9291 return visitData.keySet();
9392 }
9493
9594 public VisitData getVisitData(ModuleRevisionId mrid) {
96 VisitData result = (VisitData) visitData.get(mrid);
95 VisitData result = visitData.get(mrid);
9796
9897 if (result == null) {
9998 // search again, now ignore the missing extra attributes
100 for (Iterator it = visitData.entrySet().iterator(); it.hasNext();) {
101 Map.Entry entry = (Entry) it.next();
102 ModuleRevisionId current = (ModuleRevisionId) entry.getKey();
99 for (Map.Entry<ModuleRevisionId, VisitData> entry : visitData.entrySet()) {
100 ModuleRevisionId current = entry.getKey();
103101
104102 if (isSubMap(mrid.getAttributes(), current.getAttributes())) {
105 result = (VisitData) entry.getValue();
103 result = entry.getValue();
106104 break;
107105 }
108106 }
114112 /**
115113 * Checks whether one map is a sub-map of the other.
116114 */
117 private static boolean isSubMap(Map map1, Map map2) {
115 private static <K, V> boolean isSubMap(Map<K, V> map1, Map<K, V> map2) {
118116 int map1Size = map1.size();
119117 int map2Size = map2.size();
120118
122120 return map1.equals(map2);
123121 }
124122
125 Map smallest = map1Size < map2Size ? map1 : map2;
126 Map largest = map1Size < map2Size ? map2 : map1;
127
128 for (Iterator it = smallest.entrySet().iterator(); it.hasNext();) {
129 Map.Entry entry = (Entry) it.next();
123 Map<K, V> smallest = map1Size < map2Size ? map1 : map2;
124 Map<K, V> largest = map1Size < map2Size ? map2 : map1;
125
126 for (Map.Entry<K, V> entry : smallest.entrySet()) {
130127
131128 if (!largest.containsKey(entry.getKey())) {
132129 return false;
143140 }
144141
145142 private static boolean isEqual(Object obj1, Object obj2) {
146 if (obj1 == obj2) {
147 return true;
148 }
149
150 if (obj1 == null) {
151 return obj2 == null;
152 }
153
154 if (obj2 == null) {
155 return obj1 == null;
156 }
157
158 return obj1.equals(obj2);
143 return obj1 == obj2 || obj1 != null && obj2 != null && obj1.equals(obj2);
159144 }
160145
161146 /**
162147 * Returns the VisitNode currently visited, or <code>null</code> if there is no node currently
163148 * visited in this context.
164 *
149 *
165150 * @return the VisitNode currently visited
166151 */
167152 public VisitNode getCurrentVisitNode() {
171156 /**
172157 * Sets the currently visited node. WARNING: This should only be called by Ivy core
173158 * ResolveEngine!
174 *
175 * @param currentVisitNode
159 *
160 * @param currentVisitNode VisitNode
176161 */
177162 void setCurrentVisitNode(VisitNode currentVisitNode) {
178163 this.currentVisitNode = currentVisitNode;
197182 /**
198183 * Updates the visit data currently associated with the given mrid with the given node and the
199184 * visit nodes of the old visitData for the given rootModuleConf
200 *
185 *
201186 * @param mrid
202187 * the module revision id for which the update should be done
203188 * @param node
218203 }
219204 // replace visit data in Map (discards old one)
220205 this.visitData.put(mrid, keptVisitData);
221 // update visit data with discarde visit nodes
206 // update visit data with discarded visit nodes
222207 keptVisitData.addVisitNodes(rootModuleConf, visitData.getVisitNodes(rootModuleConf));
223208
224209 report.updateDependency(mrid, node);
257242 }
258243
259244 void blacklist(IvyNode node) {
260 for (Iterator iter = visitData.entrySet().iterator(); iter.hasNext();) {
261 Entry entry = (Entry) iter.next();
262 VisitData vdata = (VisitData) entry.getValue();
263 if (vdata.getNode() == node && !node.getResolvedId().equals(entry.getKey())) {
245 Iterator<Map.Entry<ModuleRevisionId, VisitData>> iter = visitData.entrySet().iterator();
246 while (iter.hasNext()) {
247 Map.Entry<ModuleRevisionId, VisitData> entry = iter.next();
248 if (entry.getValue().getNode() == node && !node.getResolvedId().equals(entry.getKey())) {
264249 // this visit data was associated with the blacklisted node,
265250 // we discard this association
266251 iter.remove();
271256 public boolean isBlacklisted(String rootModuleConf, ModuleRevisionId mrid) {
272257 IvyNode node = getNode(mrid);
273258
274 // if (node == null) {
275 // // search again, now ignore the extra attributes
276 // // TODO: maybe we should search the node that has at least the
277 // // same attributes as mrid
278 // for (Iterator it = visitData.entrySet().iterator(); it.hasNext();) {
279 // Map.Entry entry = (Entry) it.next();
280 // ModuleRevisionId current = (ModuleRevisionId) entry.getKey();
281 // if (current.getModuleId().equals(mrid.getModuleId())
282 // && current.getRevision().equals(mrid.getRevision())) {
283 // VisitData data = (VisitData) entry.getValue();
284 // node = data.getNode();
285 // break;
286 // }
287 // }
288 // }
289 //
259 /*
260 if (node == null) {
261 // search again, now ignore the extra attributes
262 // TODO: maybe we should search the node that has at least the same attributes as mrid
263 for (Map.Entry<ModuleRevisionId, VisitData> entry : visitData.entrySet()) {
264 ModuleRevisionId current = entry.getKey();
265 if (current.getModuleId().equals(mrid.getModuleId())
266 && current.getRevision().equals(mrid.getRevision())) {
267 VisitData data = entry.getValue();
268 node = data.getNode();
269 break;
270 }
271 }
272 }
273 */
274
290275 return node != null && node.isBlacklisted(rootModuleConf);
291276 }
292277
297282 VisitNode current = getCurrentVisitNode();
298283 if (current != null) {
299284 // mediating dd through dependers stack
300 List dependers = new ArrayList(current.getPath());
285 List<VisitNode> dependers = new ArrayList<>(current.getPath());
301286 // the returned path contains the currently visited node, we are only interested in
302 // the dependers, so we remove the currently visted node from the end
287 // the dependers, so we remove the currently visited node from the end
303288 dependers.remove(dependers.size() - 1);
304289 // we want to apply mediation going up in the dependers stack, not the opposite
305290 Collections.reverse(dependers);
306 for (Iterator iterator = dependers.iterator(); iterator.hasNext();) {
307 VisitNode n = (VisitNode) iterator.next();
291 for (VisitNode n : dependers) {
308292 ModuleDescriptor md = n.getDescriptor();
309293 if (md != null) {
310294 dd = md.mediate(dd);
328312 * this decision, even when included in a chain. The chain responsibility is only to set this
329313 * current resolved module revision to enable the resolver to take the decision.
330314 * </p>
331 *
315 *
332316 * @param mr
333317 * the last {@link ResolvedModuleRevision} which has been currently resolved.
334318 */
341325 * <p>
342326 * It can be <code>null</code>.
343327 * </p>
344 *
328 *
345329 * @return the last {@link ResolvedModuleRevision} which has been currently resolved.
346330 */
347331 public ResolvedModuleRevision getCurrentResolvedModuleRevision() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 import java.util.Date;
2929 import java.util.HashMap;
3030 import java.util.HashSet;
31 import java.util.Iterator;
3231 import java.util.LinkedHashSet;
3332 import java.util.List;
34 import java.util.ListIterator;
3533 import java.util.Map;
3634 import java.util.Properties;
3735 import java.util.Set;
7775 * {@link #resolve(URL)} which allow to simply resolve dependencies of a single module descriptor,
7876 * or more complete one, like the {@link #resolve(ModuleDescriptor, ResolveOptions)} which allows to
7977 * provide options to the resolution engine.
80 *
78 *
8179 * @see ResolveOptions
8280 */
8381 public class ResolveEngine {
8785
8886 private SortEngine sortEngine;
8987
90 private Set fetchedSet = new HashSet();
91
9288 private DependencyResolver dictatorResolver;
9389
9490 /**
9591 * Constructs a ResolveEngine.
96 *
92 *
9793 * @param settings
9894 * the settings to use to configure the engine. Must not be null.
9995 * @param eventManager
113109 /**
114110 * Returns the currently configured dictator resolver, which when non null is used in place of
115111 * any specified resolver in the {@link IvySettings}
116 *
112 *
117113 * @return the currently configured dictator resolver, may be null.
118114 */
119115 public DependencyResolver getDictatorResolver() {
123119 /**
124120 * Sets a dictator resolver, which is used in place of regular dependency resolver for
125121 * subsequent dependency resolution by this engine.
126 *
122 *
127123 * @param dictatorResolver
128124 * the dictator resolver to use in this engine, null if regular settings should used
129125 */
143139 /**
144140 * Resolves the module identified by the given mrid with its dependencies if transitive is set
145141 * to true.
142 *
143 * @param mrid ModuleRevisionId
144 * @param options ResolveOptions
145 * @param changing boolean
146 * @return ResolveReport
147 * @throws ParseException if something goes wrong
148 * @throws IOException if something goes wrong
146149 */
147150 public ResolveReport resolve(final ModuleRevisionId mrid, ResolveOptions options,
148151 boolean changing) throws ParseException, IOException {
177180
178181 /**
179182 * Resolve dependencies of a module described by an ivy file.
183 *
184 * @param ivySource URL
185 * @param options ResolveOptions
186 * @return ResolveReport
187 * @throws ParseException if something goes wrong
188 * @throws IOException if something goes wrong
180189 */
181190 public ResolveReport resolve(URL ivySource, ResolveOptions options) throws ParseException,
182191 IOException {
198207
199208 /**
200209 * Resolve dependencies of a module described by a module descriptor.
210 * @param md ModuleDescriptor
211 * @param options ResolveOptions
212 * @return ResolveReport
213 * @throws ParseException if something goes wrong
214 * @throws IOException if something goes wrong
201215 */
202216 public ResolveReport resolve(ModuleDescriptor md, ResolveOptions options)
203217 throws ParseException, IOException {
250264 .getResolvedModuleRevisionId());
251265 Properties props = new Properties();
252266 if (dependencies.length > 0) {
253 Map forcedRevisions = new HashMap();
254 for (int i = 0; i < dependencies.length; i++) {
255 if (dependencies[i].getModuleRevision() != null
256 && dependencies[i].getModuleRevision().isForce()) {
257 forcedRevisions.put(dependencies[i].getModuleId(),
258 dependencies[i].getResolvedId());
267 Map<ModuleId, ModuleRevisionId> forcedRevisions = new HashMap<>();
268 for (IvyNode dependency : dependencies) {
269 if (dependency.getModuleRevision() != null
270 && dependency.getModuleRevision().isForce()) {
271 forcedRevisions.put(dependency.getModuleId(),
272 dependency.getResolvedId());
259273 }
260274 }
261275
262276 IvyNode root = dependencies[0].getRoot();
263277
264 // <ModuleId,IvyNode>();
265 Map topLevelDeps = new HashMap(); //
266 for (int i = 0; i < dependencies.length; i++) {
267 if (!dependencies[i].hasProblem()) {
268 DependencyDescriptor dd = dependencies[i].getDependencyDescriptor(root);
278 Map<ModuleId, IvyNode> topLevelDeps = new HashMap<>();
279 for (IvyNode dependency : dependencies) {
280 if (!dependency.hasProblem()) {
281 DependencyDescriptor dd = dependency.getDependencyDescriptor(root);
269282 if (dd != null) {
270 ModuleId orgMod = dependencies[i].getModuleId();
271 topLevelDeps.put(orgMod, dependencies[i]);
283 ModuleId orgMod = dependency.getModuleId();
284 topLevelDeps.put(orgMod, dependency);
272285 }
273286 }
274287 }
275288
276 for (int i = 0; i < dependencies.length; i++) {
277 if (!dependencies[i].hasProblem() && !dependencies[i].isCompletelyEvicted()) {
278 DependencyDescriptor dd = dependencies[i].getDependencyDescriptor(root);
289 for (IvyNode dependency : dependencies) {
290 if (!dependency.hasProblem() && !dependency.isCompletelyEvicted()) {
291 DependencyDescriptor dd = dependency.getDependencyDescriptor(root);
279292 if (dd == null) {
280 ModuleId mid = dependencies[i].getModuleId();
281 IvyNode tlDep = (IvyNode) topLevelDeps.get(mid);
293 ModuleId mid = dependency.getModuleId();
294 IvyNode tlDep = topLevelDeps.get(mid);
282295 if (tlDep != null) {
283296 dd = tlDep.getDependencyDescriptor(root);
284297 }
285298 }
286299 if (dd != null) {
287 ModuleRevisionId depResolvedId = dependencies[i].getResolvedId();
288 ModuleDescriptor depDescriptor = dependencies[i].getDescriptor();
300 ModuleRevisionId depResolvedId = dependency.getResolvedId();
301 ModuleDescriptor depDescriptor = dependency.getDescriptor();
289302 ModuleRevisionId depRevisionId = dd.getDependencyRevisionId();
290 ModuleRevisionId forcedRevisionId = (ModuleRevisionId) forcedRevisions
291 .get(dependencies[i].getModuleId());
292
293 if (dependencies[i].getModuleRevision() != null
294 && dependencies[i].getModuleRevision().isForce()
303 ModuleRevisionId forcedRevisionId = forcedRevisions.get(dependency
304 .getModuleId());
305
306 if (dependency.getModuleRevision() != null
307 && dependency.getModuleRevision().isForce()
295308 && !depResolvedId.equals(depRevisionId)
296309 && !settings.getVersionMatcher().isDynamic(depRevisionId)) {
297310 // if we were forced to this revision and we
303316
304317 if (depResolvedId == null) {
305318 throw new NullPointerException("getResolvedId() is null for "
306 + dependencies[i].toString());
319 + dependency.toString());
307320 }
308321 if (depRevisionId == null) {
309322 throw new NullPointerException("getDependencyRevisionId() "
372385 report.output(settings.getReportOutputters(), cacheMgr, options);
373386 }
374387
375 public void downloadArtifacts(ResolveReport report, Filter artifactFilter,
388 public void downloadArtifacts(ResolveReport report, Filter<Artifact> artifactFilter,
376389 DownloadOptions options) {
377390 long start = System.currentTimeMillis();
378 IvyNode[] dependencies = (IvyNode[]) report.getDependencies().toArray(
379 new IvyNode[report.getDependencies().size()]);
380
381 eventManager.fireIvyEvent(new PrepareDownloadEvent((Artifact[]) report.getArtifacts()
382 .toArray(new Artifact[report.getArtifacts().size()])));
391
392 eventManager.fireIvyEvent(new PrepareDownloadEvent(report.getArtifacts().toArray(
393 new Artifact[report.getArtifacts().size()])));
383394
384395 long totalSize = 0;
385 for (int i = 0; i < dependencies.length; i++) {
396 for (IvyNode dependency : report.getDependencies()) {
386397 checkInterrupted();
387398 // download artifacts required in all asked configurations
388 if (!dependencies[i].isCompletelyEvicted() && !dependencies[i].hasProblem()
389 && dependencies[i].getModuleRevision() != null) {
390 DependencyResolver resolver = dependencies[i].getModuleRevision()
399 if (!dependency.isCompletelyEvicted() && !dependency.hasProblem()
400 && dependency.getModuleRevision() != null) {
401 DependencyResolver resolver = dependency.getModuleRevision()
391402 .getArtifactResolver();
392 Artifact[] selectedArtifacts = dependencies[i].getSelectedArtifacts(artifactFilter);
403 Artifact[] selectedArtifacts = dependency.getSelectedArtifacts(artifactFilter);
393404 DownloadReport dReport = resolver.download(selectedArtifacts, options);
394 ArtifactDownloadReport[] adrs = dReport.getArtifactsReports();
395 for (int j = 0; j < adrs.length; j++) {
396 if (adrs[j].getDownloadStatus() == DownloadStatus.FAILED) {
397 if (adrs[j].getArtifact().getExtraAttribute("ivy:merged") != null) {
398 Message.warn("\tmerged artifact not found: " + adrs[j].getArtifact()
405 for (ArtifactDownloadReport adr : dReport.getArtifactsReports()) {
406 if (adr.getDownloadStatus() == DownloadStatus.FAILED) {
407 if (adr.getArtifact().getExtraAttribute("ivy:merged") != null) {
408 Message.warn("\tmerged artifact not found: " + adr.getArtifact()
399409 + ". It was required in "
400 + adrs[j].getArtifact().getExtraAttribute("ivy:merged"));
410 + adr.getArtifact().getExtraAttribute("ivy:merged"));
401411 } else {
402 Message.warn("\t" + adrs[j]);
403 resolver.reportFailure(adrs[j].getArtifact());
412 Message.warn("\t" + adr);
413 resolver.reportFailure(adr.getArtifact());
404414 }
405 } else if (adrs[j].getDownloadStatus() == DownloadStatus.SUCCESSFUL) {
406 totalSize += adrs[j].getSize();
415 } else if (adr.getDownloadStatus() == DownloadStatus.SUCCESSFUL) {
416 totalSize += adr.getSize();
407417 }
408418 }
409419 // update concerned reports
410 String[] dconfs = dependencies[i].getRootModuleConfigurations();
411 for (int j = 0; j < dconfs.length; j++) {
420 for (String dconf : dependency.getRootModuleConfigurations()) {
412421 // the report itself is responsible to take into account only
413422 // artifacts required in its corresponding configuration
414423 // (as described by the Dependency object)
415 if (dependencies[i].isEvicted(dconfs[j])
416 || dependencies[i].isBlacklisted(dconfs[j])) {
417 report.getConfigurationReport(dconfs[j]).addDependency(dependencies[i]);
424 if (dependency.isEvicted(dconf)
425 || dependency.isBlacklisted(dconf)) {
426 report.getConfigurationReport(dconf).addDependency(dependency);
418427 } else {
419 report.getConfigurationReport(dconfs[j]).addDependency(dependencies[i],
420 dReport);
428 report.getConfigurationReport(dconf).addDependency(dependency,
429 dReport);
421430 }
422431 }
423432 }
436445 * It is possible to track the progression of the download using classical ivy progress
437446 * monitoring feature (see addTransferListener).
438447 * </p>
439 *
448 *
440449 * @param artifact
441450 * the artifact to download
451 * @param options DownloadOptions
442452 * @return a report concerning the download
443453 * @see #download(ArtifactOrigin, DownloadOptions)
444454 */
451461 /**
452462 * Locates an artifact in dependency resolvers, and return its location if it can be located and
453463 * actually exists, or an unknown {@link ArtifactOrigin} in other cases.
454 *
464 *
455465 * @param artifact
456466 * the artifact to locate.
457467 * @return the artifact location, should be tested with
477487 * It is possible to track the progression of the download using classical ivy progress
478488 * monitoring feature (see addTransferListener).
479489 * </p>
480 *
490 *
481491 * @param origin
482492 * the artifact origin to materialize
493 * @param options DownloadOptions
483494 * @return a report concerning the download
484495 * @see #download(Artifact, DownloadOptions)
485496 * @see #locate(Artifact)
494505 * Resolve the dependencies of a module without downloading corresponding artifacts. The module
495506 * to resolve is given by its ivy file URL. This method requires appropriate configuration of
496507 * the ivy instance, especially resolvers.
497 *
508 *
498509 * @param ivySource
499510 * url of the ivy file to use for dependency resolving
500 * @param confs
501 * an array of configuration names to resolve - must not be null nor empty
502 * @param getCache
503 * the cache to use - default cache is used if null
504 * @param date
505 * the date to which resolution must be done - may be null
511 * @param options
512 * ditto
506513 * @return an array of the resolved dependencies
507514 * @throws ParseException
508515 * if a parsing problem occurred in the ivy file
523530 * <p>
524531 * The <code>IvyNode</code>s are ordered from the most dependent to the less dependent, so that
525532 * an IvyNode is always found in the list after all IvyNode depending directly on it.
526 *
533 *
527534 * @param md
528535 * the descriptor of the module for which we want to get dependencies - must not be
529536 * null
540547 throw new NullPointerException("module descriptor must not be null");
541548 }
542549 String[] confs = options.getConfs(md);
543 Collection missingConfs = new ArrayList();
544 for (int i = 0; i < confs.length; i++) {
545 if (confs[i] == null) {
550 Collection<String> missingConfs = new ArrayList<>();
551 for (String conf : confs) {
552 if (conf == null) {
546553 throw new NullPointerException("null conf not allowed: confs where: "
547554 + Arrays.asList(confs));
548555 }
549556
550 if (md.getConfiguration(confs[i]) == null) {
551 missingConfs.add(" '" + confs[i] + "' ");
557 if (md.getConfiguration(conf) == null) {
558 missingConfs.add(" '" + conf + "' ");
552559 }
553560 }
554561 if (!missingConfs.isEmpty()) {
569576 }
570577 IvyNode rootNode = new IvyNode(data, md);
571578
572 for (int i = 0; i < confs.length; i++) {
573 Message.verbose("resolving dependencies for configuration '" + confs[i] + "'");
574 // for each configuration we clear the cache of what's been fetched
575 fetchedSet.clear();
579 for (String conf : confs) {
580 Message.verbose("resolving dependencies for configuration '" + conf + "'");
576581
577582 ConfigurationResolveReport confReport = null;
578583 if (report != null) {
579 confReport = report.getConfigurationReport(confs[i]);
584 confReport = report.getConfigurationReport(conf);
580585 if (confReport == null) {
581 confReport = new ConfigurationResolveReport(this, md, confs[i], reportDate,
586 confReport = new ConfigurationResolveReport(this, md, conf, reportDate,
582587 options);
583 report.addReport(confs[i], confReport);
588 report.addReport(conf, confReport);
584589 }
585590 }
586591 // we reuse the same resolve data with a new report for each conf
587592 data.setReport(confReport);
588593
589594 // update the root module conf we are about to fetch
590 VisitNode root = new VisitNode(data, rootNode, null, confs[i], null);
591 root.setRequestedConf(confs[i]);
592 rootNode.updateConfsToFetch(Collections.singleton(confs[i]));
595 VisitNode root = new VisitNode(data, rootNode, null, conf, null);
596 root.setRequestedConf(conf);
597 rootNode.updateConfsToFetch(Collections.singleton(conf));
593598
594599 // go fetch !
595600 boolean fetched = false;
596601 while (!fetched) {
597602 try {
598 fetchDependencies(root, confs[i], false);
603 fetchDependencies(root, conf, new HashSet<String>(), false);
599604 fetched = true;
600605 } catch (RestartResolveProcess restart) {
601606 Message.verbose("====================================================");
602607 Message.verbose("= RESTARTING RESOLVE PROCESS");
603608 Message.verbose("= " + restart.getMessage());
604609 Message.verbose("====================================================");
605 fetchedSet.clear();
606610 }
607611 }
608612
609613 // clean data
610 for (Iterator iter = data.getNodes().iterator(); iter.hasNext();) {
611 IvyNode dep = (IvyNode) iter.next();
614 for (IvyNode dep : data.getNodes()) {
612615 dep.clean();
613616 }
614617 }
615618
616 // prune and reverse sort fectched dependencies
617 Collection nodes = data.getNodes();
619 // prune and reverse sort fetched dependencies
620 Collection<IvyNode> nodes = data.getNodes();
618621 // use a Set to avoid duplicates, linked to preserve order
619 Collection dependencies = new LinkedHashSet(nodes.size());
620 for (Iterator iter = nodes.iterator(); iter.hasNext();) {
621 IvyNode node = (IvyNode) iter.next();
622 Collection<IvyNode> dependencies = new LinkedHashSet<>(nodes.size());
623 for (IvyNode node : nodes) {
622624 if (node != null && !node.isRoot() && !node.isCompletelyBlacklisted()) {
623625 dependencies.add(node);
624626 }
625627 }
626 List sortedDependencies = sortEngine.sortNodes(dependencies, SortOptions.SILENT);
628 List<IvyNode> sortedDependencies = sortEngine.sortNodes(dependencies,
629 SortOptions.SILENT);
627630 Collections.reverse(sortedDependencies);
628631
629 handleTransiviteEviction(md, confs, data, sortedDependencies);
630
631 return (IvyNode[]) dependencies.toArray(new IvyNode[dependencies.size()]);
632 handleTransitiveEviction(md, confs, data, sortedDependencies);
633
634 return dependencies.toArray(new IvyNode[dependencies.size()]);
632635 } finally {
633636 IvyContext.popContext();
634637 }
635638 }
636639
637 private void handleTransiviteEviction(ModuleDescriptor md, String[] confs, ResolveData data,
638 List sortedDependencies) {
640 private void handleTransitiveEviction(ModuleDescriptor md, String[] confs, ResolveData data,
641 List<IvyNode> sortedDependencies) {
639642 // handle transitive eviction now:
640643 // if a module has been evicted then all its dependencies required only by it should be
641644 // evicted too. Since nodes are now sorted from the more dependent to the less one, we
642645 // can traverse the list and check only the direct parent and not all the ancestors
643 for (ListIterator iter = sortedDependencies.listIterator(); iter.hasNext();) {
644 IvyNode node = (IvyNode) iter.next();
646 for (IvyNode node : sortedDependencies) {
645647 if (!node.isCompletelyEvicted()) {
646 for (int i = 0; i < confs.length; i++) {
647 IvyNodeCallers.Caller[] callers = node.getCallers(confs[i]);
648 for (String conf : confs) {
649 IvyNodeCallers.Caller[] callers = node.getCallers(conf);
648650 if (settings.debugConflictResolution()) {
649651 Message.debug("checking if " + node.getId()
650 + " is transitively evicted in " + confs[i]);
652 + " is transitively evicted in " + conf);
651653 }
652654 boolean allEvicted = callers.length > 0;
653 for (int j = 0; j < callers.length; j++) {
654 if (callers[j].getModuleRevisionId().equals(md.getModuleRevisionId())) {
655 for (IvyNodeCallers.Caller caller : callers) {
656 if (caller.getModuleRevisionId().equals(md.getModuleRevisionId())) {
655657 // the caller is the root module itself, it can't be evicted
656658 allEvicted = false;
657659 break;
658660 } else {
659 IvyNode callerNode = data.getNode(callers[j].getModuleRevisionId());
661 IvyNode callerNode = data.getNode(caller.getModuleRevisionId());
660662 if (callerNode == null) {
661663 Message.warn("ivy internal error: no node found for "
662 + callers[j].getModuleRevisionId() + ": looked in "
664 + caller.getModuleRevisionId() + ": looked in "
663665 + data.getNodeIds() + " and root module id was "
664666 + md.getModuleRevisionId());
665 } else if (!callerNode.isEvicted(confs[i])) {
667 } else if (!callerNode.isEvicted(conf)) {
666668 allEvicted = false;
667669 break;
668670 } else {
675677 }
676678 if (allEvicted) {
677679 Message.verbose("all callers are evicted for " + node + ": evicting too");
678 node.markEvicted(confs[i], null, null, null);
680 node.markEvicted(conf, null, null, null);
679681 } else {
680682 if (settings.debugConflictResolution()) {
681683 Message.debug(node.getId()
688690 }
689691 }
690692
691 private void fetchDependencies(VisitNode node, String conf, boolean shouldBePublic) {
693 private void fetchDependencies(VisitNode node, String conf, Set<String> fetchedSet, boolean shouldBePublic) {
692694 checkInterrupted();
693695 long start = System.currentTimeMillis();
694696 if (node.getParent() != null) {
703705 data.setCurrentVisitNode(node);
704706 DependencyDescriptor dd = node.getDependencyDescriptor();
705707 VersionMatcher versionMatcher = node.getNode().getData().getSettings().getVersionMatcher();
706 if (dd != null
707 && !(node.getRoot() == node.getParent() && versionMatcher.isDynamic(dd
708 .getDependencyRevisionId()))) {
708 if (dd != null && !(node.getRoot() == node.getParent()
709 && versionMatcher.isDynamic(dd.getDependencyRevisionId()))) {
709710 /*
710711 * we don't resolve conflicts before loading data for direct dependencies on dynamic
711712 * revisions, so that direct dynamic revisions are always resolved, which is mandatory
720721 // dependency to take the decision
721722 resolveConflict(node, conf);
722723 if (!node.isEvicted() && !node.isCircular()) {
723 String[] confs = node.getRealConfs(conf);
724 for (int i = 0; i < confs.length; i++) {
725 doFetchDependencies(node, confs[i]);
724 for (String rconf : node.getRealConfs(conf)) {
725 doFetchDependencies(node, rconf, fetchedSet);
726726 }
727727 }
728728 } else if (!node.hasProblem()) {
729729 // the node has not been loaded but hasn't problem: it was already loaded
730730 // => we just have to update its dependencies data
731731 if (!node.isEvicted() && !node.isCircular()) {
732 String[] confs = node.getRealConfs(conf);
733 for (int i = 0; i < confs.length; i++) {
734 doFetchDependencies(node, confs[i]);
732 for (String rconf : node.getRealConfs(conf)) {
733 doFetchDependencies(node, rconf, fetchedSet);
735734 }
736735 }
737736 }
739738 // update selected nodes with confs asked in evicted one
740739 EvictionData ed = node.getEvictedData();
741740 if (ed.getSelected() != null) {
742 for (Iterator iter = ed.getSelected().iterator(); iter.hasNext();) {
743 IvyNode selected = (IvyNode) iter.next();
741 for (IvyNode selected : ed.getSelected()) {
744742 if (!selected.isLoaded()) {
745743 // the node is not yet loaded, we can simply update its set of
746744 // configurations to fetch
748746 } else {
749747 // the node has already been loaded, we must fetch its dependencies in the
750748 // required conf
751 fetchDependencies(node.gotoNode(selected), conf, true);
749 fetchDependencies(node.gotoNode(selected), conf, fetchedSet, true);
752750 }
753751 }
754752 }
760758 data.setCurrentVisitNode(parentVisitNode);
761759 }
762760
763 private void doFetchDependencies(VisitNode node, String conf) {
761 private void doFetchDependencies(VisitNode node, String conf, Set<String> fetchedSet) {
764762 Configuration c = node.getConfiguration(conf);
765763 if (c == null) {
766764 if (!node.isConfRequiredByMergedUsageOnly(conf)) {
786784 if (extendedConfs.length > 0) {
787785 node.updateConfsToFetch(Arrays.asList(extendedConfs));
788786 }
789 for (int i = 0; i < extendedConfs.length; i++) {
790 fetchDependencies(node, extendedConfs[i], false);
787 for (String extendedConf : extendedConfs) {
788 fetchDependencies(node, extendedConf, fetchedSet, false);
791789 }
792790
793791 // now we can actually resolve this configuration dependencies
794 if (!isDependenciesFetched(node.getNode(), conf) && node.isTransitive()) {
795 Collection/* <VisitNode> */dependencies = node.getDependencies(conf);
796 for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
797 VisitNode dep = (VisitNode) iter.next();
792 if (!isDependenciesFetched(node.getNode(), conf, fetchedSet) && node.isTransitive()) {
793 for (VisitNode dep : node.getDependencies(conf)) {
798794 dep.useRealNode(); // the node may have been resolved to another real one while
799795 // resolving other deps
800 String[] confs = dep.getRequiredConfigurations(node, conf);
801 for (int i = 0; i < confs.length; i++) {
802 fetchDependencies(dep, confs[i], true);
796 for (String rconf : dep.getRequiredConfigurations(node, conf)) {
797 fetchDependencies(dep, rconf, fetchedSet, true);
803798 }
804799 if (!dep.isEvicted() && !dep.hasProblem()) {
805800 // if there are still confs to fetch (usually because they have
806801 // been updated when evicting another module), we fetch them now
807 confs = dep.getConfsToFetch();
808 for (int i = 0; i < confs.length; i++) {
802 for (String fconf : dep.getConfsToFetch()) {
809803 // shouldBeFixed=false to because some of those dependencies might
810804 // be private when they were actually extending public conf.
811805 // Should we keep two list of confs to fetch (private&public)?
812806 // I don't think, visibility is already checked, and a change in the
813807 // configuration between version might anyway have worse problems.
814 fetchDependencies(dep, confs[i], false);
815 }
816 }
817 }
818 markDependenciesFetched(node.getNode(), conf);
819 }
820 // we have finiched with this configuration, if it was the original requested conf
808 fetchDependencies(dep, fconf, fetchedSet, false);
809 }
810 }
811 }
812 markDependenciesFetched(node.getNode(), conf, fetchedSet);
813 }
814 // we have finished with this configuration, if it was the original requested conf
821815 // we can clean it now
822816 if (requestedConfSet) {
823817 node.setRequestedConf(null);
827821
828822 /**
829823 * Returns true if we've already fetched the dependencies for this node and configuration
830 *
824 *
831825 * @param node
832826 * node to check
833827 * @param conf
834828 * configuration to check
835829 * @return true if we've already fetched this dependency
836830 */
837 private boolean isDependenciesFetched(IvyNode node, String conf) {
831 private boolean isDependenciesFetched(IvyNode node, String conf, Set<String> fetchedSet) {
838832 String key = getDependenciesFetchedKey(node, conf);
839833 return fetchedSet.contains(key);
840834 }
841835
842 private void markDependenciesFetched(IvyNode node, String conf) {
836 private void markDependenciesFetched(IvyNode node, String conf, Set<String> fetchedSet) {
843837 String key = getDependenciesFetchedKey(node, conf);
844838 fetchedSet.add(key);
845839 }
846840
847841 private String getDependenciesFetchedKey(IvyNode node, String conf) {
848842 ModuleRevisionId moduleRevisionId = node.getResolvedId();
849 String key = moduleRevisionId.getOrganisation() + "|" + moduleRevisionId.getName() + "|"
843 return moduleRevisionId.getOrganisation() + "|" + moduleRevisionId.getName() + "|"
850844 + moduleRevisionId.getRevision() + "|" + conf;
851 return key;
852845 }
853846
854847 private void resolveConflict(VisitNode node, String conf) {
855 resolveConflict(node, node.getParent(), conf, Collections.EMPTY_SET);
848 resolveConflict(node, node.getParent(), conf, Collections.<IvyNode> emptySet());
856849 }
857850
858851 /**
859852 * Resolves conflict for the given node in the given ancestor. This method do conflict
860853 * resolution in ancestor parents recursively, unless not necessary.
861 *
854 *
862855 * @param node
863856 * the node for which conflict resolution should be done
864857 * @param ancestor
865858 * the ancestor in which the conflict resolution should be done
859 * @param conf String
866860 * @param toevict
867861 * a collection of IvyNode to evict (as computed by conflict resolution in
868862 * descendants of ancestor)
869863 * @return true if conflict resolution has been done, false it can't be done yet
870864 */
871865 private boolean resolveConflict(VisitNode node, VisitNode ancestor, String conf,
872 Collection toevict) {
866 Collection<IvyNode> toevict) {
873867 if (ancestor == null || node == ancestor) {
874868 return true;
875869 }
906900 }
907901
908902 // compute conflicts
909 Set resolvedNodes = ancestor.getNode().getResolvedNodes(node.getModuleId(),
903 Set<IvyNode> resolvedNodes = ancestor.getNode().getResolvedNodes(node.getModuleId(),
910904 node.getRootModuleConf());
911905 resolvedNodes.addAll(ancestor.getNode().getPendingConflicts(node.getRootModuleConf(),
912906 node.getModuleId()));
913 Collection conflicts = computeConflicts(node, ancestor, conf, toevict, resolvedNodes);
914
915 ConflictManager conflictManager = ancestor.getNode().getConflictManager(node.getModuleId());
916
917 Collection resolved = resolveConflicts(node, ancestor, conflicts, conflictManager);
907 Collection<IvyNode> conflicts = computeConflicts(node, ancestor, conf, toevict,
908 resolvedNodes);
909
910 ConflictManager conflictManager = null;
911 for (VisitNode current : ancestor.getPath()) {
912 ModuleDescriptor descriptor = current.getNode().getDescriptor();
913 if (descriptor == null) {
914 throw new IllegalStateException(
915 "impossible to get conflict manager when data has not been loaded. IvyNode = "
916 + current.getNode());
917 }
918
919 conflictManager = descriptor.getConflictManager(node.getModuleId());
920 if (conflictManager != null) {
921 break;
922 }
923 }
924
925 if (conflictManager == null) {
926 conflictManager = settings.getConflictManager(node.getModuleId());
927 }
928
929 Collection<IvyNode> resolved = resolveConflicts(node, ancestor, conflicts, conflictManager);
918930
919931 if (resolved == null) {
920932 if (debugConflictResolution) {
938950 toevict = resolvedNodes;
939951 toevict.removeAll(resolved);
940952
941 for (Iterator iter = toevict.iterator(); iter.hasNext();) {
942 IvyNode te = (IvyNode) iter.next();
953 for (IvyNode te : toevict) {
943954 te.markEvicted(node.getRootModuleConf(), ancestor.getNode(), conflictManager,
944955 resolved);
945956
955966 ancestor.getNode().setResolvedNodes(node.getModuleId(), node.getRootModuleConf(),
956967 resolved);
957968
958 Collection evicted = new HashSet(ancestor.getNode().getEvictedNodes(node.getModuleId(),
959 node.getRootModuleConf()));
969 Collection<IvyNode> evicted = new HashSet<>(ancestor.getNode().getEvictedNodes(
970 node.getModuleId(), node.getRootModuleConf()));
960971 evicted.removeAll(resolved);
961972 evicted.addAll(toevict);
962973 ancestor.getNode().setEvictedNodes(node.getModuleId(), node.getRootModuleConf(),
963974 evicted);
964975 ancestor.getNode().setPendingConflicts(node.getModuleId(), node.getRootModuleConf(),
965 Collections.EMPTY_SET);
976 Collections.<IvyNode> emptySet());
966977
967978 return resolveConflict(node, ancestor.getParent(), conf, toevict);
968979 } else {
976987
977988 // it's time to update parent resolved and evicted with what was found
978989
979 Collection evicted = new HashSet(ancestor.getNode().getEvictedNodes(node.getModuleId(),
980 node.getRootModuleConf()));
990 Collection<IvyNode> evicted = new HashSet<>(ancestor.getNode().getEvictedNodes(
991 node.getModuleId(), node.getRootModuleConf()));
981992 toevict.removeAll(resolved);
982993 evicted.removeAll(resolved);
983994 evicted.addAll(toevict);
985996 ancestor.getNode().setEvictedNodes(node.getModuleId(), node.getRootModuleConf(),
986997 evicted);
987998 ancestor.getNode().setPendingConflicts(node.getModuleId(), node.getRootModuleConf(),
988 Collections.EMPTY_SET);
999 Collections.<IvyNode> emptySet());
9891000
9901001 node.markEvicted(ancestor, conflictManager, resolved);
9911002 if (debugConflictResolution) {
9931004 }
9941005
9951006 // if resolved changed we have to go up in the graph
996 Collection prevResolved = ancestor.getNode().getResolvedNodes(node.getModuleId(),
997 node.getRootModuleConf());
1007 Collection<IvyNode> prevResolved = ancestor.getNode().getResolvedNodes(
1008 node.getModuleId(), node.getRootModuleConf());
9981009 boolean solved = true;
9991010 if (!prevResolved.equals(resolved)) {
10001011 ancestor.getNode().setResolvedNodes(node.getModuleId(), node.getRootModuleConf(),
10011012 resolved);
1002 for (Iterator iter = resolved.iterator(); iter.hasNext();) {
1003 IvyNode sel = (IvyNode) iter.next();
1013 for (IvyNode sel : resolved) {
10041014 if (!prevResolved.contains(sel)) {
10051015 solved &= resolveConflict(node.gotoNode(sel), ancestor.getParent(), conf,
10061016 toevict);
10111021 }
10121022 }
10131023
1014 private Collection resolveConflicts(VisitNode node, VisitNode ancestor, Collection conflicts,
1015 ConflictManager conflictManager) {
1024 private Collection<IvyNode> resolveConflicts(VisitNode node, VisitNode ancestor,
1025 Collection<IvyNode> conflicts, ConflictManager conflictManager) {
10161026 if (node.getParent() != ancestor
10171027 // we are not handling the direct parent
10181028
10451055 /**
10461056 * Compute possible conflicts for a node, in the context of an ancestor (a node which has a
10471057 * dependency - direct or indirect - on the node for which conflicts should be computed.
1048 *
1058 *
10491059 * @param node
10501060 * the node for which conflicts should be computed
10511061 * @param ancestor
10631073 * @return a collection of IvyNode which may be in conflict with the given node in the given
10641074 * ancestor. This collection always contain at least the given node.
10651075 */
1066 private Collection computeConflicts(VisitNode node, VisitNode ancestor, String conf,
1067 Collection toevict, Collection selectedNodes) {
1068 Collection conflicts = new LinkedHashSet();
1076 private Collection<IvyNode> computeConflicts(VisitNode node, VisitNode ancestor, String conf,
1077 Collection<IvyNode> toevict, Collection<IvyNode> selectedNodes) {
1078 Collection<IvyNode> conflicts = new LinkedHashSet<>();
10691079 conflicts.add(node.getNode());
10701080 /*
10711081 * We first try to remove all evicted nodes from the collection of selected nodes to update
10861096 data.setCurrentVisitNode(ancestor);
10871097 try {
10881098 // In this case we need to compute selected nodes again.
1089 Collection deps = ancestor.getNode().getDependencies(node.getRootModuleConf(),
1099 Collection<IvyNode> deps = ancestor.getNode().getDependencies(
1100 node.getRootModuleConf(),
10901101 ancestor.getNode().getConfigurations(node.getRootModuleConf()),
10911102 ancestor.getRequestedConf());
1092 for (Iterator iter = deps.iterator(); iter.hasNext();) {
1093 IvyNode dep = (IvyNode) iter.next();
1103 for (IvyNode dep : deps) {
10941104 if (dep.getModuleId().equals(node.getModuleId())) {
10951105 conflicts.add(dep);
10961106 }
11071117 * the parent direct dependencies in current root module conf.
11081118 */
11091119 VisitNode parent = node.getParent();
1110 Collection parentDepIvyNodes = parent.getNode().getDependencies(
1120 Collection<IvyNode> parentDepIvyNodes = parent.getNode().getDependencies(
11111121 node.getRootModuleConf(),
11121122 parent.getNode().getConfigurations(node.getRootModuleConf()),
11131123 parent.getRequestedConf());
1114 for (Iterator it = parentDepIvyNodes.iterator(); it.hasNext();) {
1115 IvyNode parentDep = (IvyNode) it.next();
1124 for (IvyNode parentDep : parentDepIvyNodes) {
11161125 if (parentDep.getModuleId().equals(node.getModuleId())) {
11171126 conflicts.add(parentDep);
11181127 }
11721181 * The mediated dependency descriptor must return the actually requested module revision id when
11731182 * the method {@link DependencyDescriptor#getDependencyRevisionId()} is called.
11741183 * </p>
1175 *
1184 *
11761185 * @param dd
11771186 * the dependency descriptor for which the requested module revision id should be
11781187 * returned
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.Date;
2020
2121 import org.apache.ivy.core.LogOptions;
22 import org.apache.ivy.core.module.descriptor.Artifact;
2223 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
2324 import org.apache.ivy.core.module.id.ModuleId;
2425 import org.apache.ivy.util.ConfigurationUtils;
2728
2829 /**
2930 * A set of options used during resolve related tasks
30 *
31 *
3132 * @see ResolveEngine
3233 */
3334 public class ResolveOptions extends LogOptions {
99100 /**
100101 * A filter to use to avoid downloading all artifacts.
101102 */
102 private Filter artifactFilter = FilterHelper.NO_FILTER;
103 private Filter<Artifact> artifactFilter = FilterHelper.NO_FILTER;
103104
104105 /**
105106 * The resolve mode to use. Should be one of {@link #RESOLVEMODES}, or <code>null</code> to use
139140 checkIfChanged = options.checkIfChanged;
140141 }
141142
142 public Filter getArtifactFilter() {
143 public Filter<Artifact> getArtifactFilter() {
143144 return artifactFilter;
144145 }
145146
146 public ResolveOptions setArtifactFilter(Filter artifactFilter) {
147 public ResolveOptions setArtifactFilter(Filter<Artifact> artifactFilter) {
147148 this.artifactFilter = artifactFilter;
148149 return this;
149150 }
151152 /**
152153 * Returns the resolve mode to use, or <code>null</code> to use settings configured resolve
153154 * mode.
154 *
155 *
155156 * @return the resolve mode to use.
156157 */
157158 public String getResolveMode() {
167168 * Indicates if the configurations use a special configuration * , *(private) or *(public). When
168169 * special configurations are used, you must have the module descriptor in order to get the list
169170 * of configurations.
170 *
171 *
172 * @return boolean
171173 * @see #getConfs()
172174 * @see #getConfs(ModuleDescriptor)
173175 */
174176 public boolean useSpecialConfs() {
175 for (int i = 0; confs != null && i < confs.length; i++) {
176 if (confs[0].startsWith("*")) {
177 return true;
178 }
179 }
180 return false;
177 return confs != null && confs[0].startsWith("*");
181178 }
182179
183180 /**
184181 * @pre can only be called if useSpecialConfs()==false. When it is true, you have to provide a
185 * module desciptor so that configurations can be resolved.
182 * module descriptor so that configurations can be resolved.
183 * @return String[]
186184 * @see #getConfs(ModuleDescriptor)
187185 */
188186 public String[] getConfs() {
194192 }
195193
196194 /**
197 * Get the aksed confs. Special confs (like *) use the moduleDescriptor to find the values *
198 *
195 * Get the asked confs. Special confs (like *) use the moduleDescriptor to find the values
196 *
199197 * @param md
200198 * Used to get the exact values for special confs.
201 * */
199 * @return String[]
200 */
202201 public String[] getConfs(ModuleDescriptor md) {
203202 // TODO add isInline, in that case, replace * by *(public).
204203 return ConfigurationUtils.replaceWildcards(confs, md);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 * Some subclasses have even a stronger power over the resolve process, like
2727 * {@link RestartResolveProcess} which orders to restart the resolve process at the start.
2828 */
29 @SuppressWarnings("serial")
2930 public class ResolveProcessException extends RuntimeException {
3031
3132 public ResolveProcessException() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5757
5858 /**
5959 * Returns the identifier of the resolved module.
60 *
60 *
6161 * @return the identifier of the resolved module.
6262 */
6363 public ModuleRevisionId getId() {
6666
6767 /**
6868 * Returns the date of publication of the resolved module.
69 *
69 *
7070 * @return the date of publication of the resolved module.
7171 */
7272 public Date getPublicationDate() {
7575
7676 /**
7777 * Returns the descriptor of the resolved module.
78 *
78 *
7979 * @return the descriptor of the resolved module.
8080 */
8181 public ModuleDescriptor getDescriptor() {
8484
8585 /**
8686 * The resolver which resolved this ResolvedModuleRevision
87 *
87 *
8888 * @return The resolver which resolved this ResolvedModuleRevision
8989 */
9090 public DependencyResolver getResolver() {
9393
9494 /**
9595 * The resolver to use to download artifacts
96 *
96 *
9797 * @return The resolver to use to download artifacts
9898 */
9999 public DependencyResolver getArtifactResolver() {
102102
103103 /**
104104 * Returns a report of the resolved module metadata artifact provisioning.
105 *
105 *
106106 * @return a report of the resolved module metadata artifact provisioning.
107107 */
108108 public MetadataArtifactDownloadReport getReport() {
116116 * This is used as an indication for CompositeResolver, to know if they should continue to look
117117 * for a better ResolvedModuleRevision if possible, or stop with this instance.
118118 * </p>
119 *
119 *
120120 * @return <code>true</code> if this resolved module revision should be forced as the one being
121121 * returned.
122122 */
125125 }
126126
127127 public boolean equals(Object obj) {
128 if (!(obj instanceof ResolvedModuleRevision)) {
129 return false;
130 }
131 return ((ResolvedModuleRevision) obj).getId().equals(getId());
128 return obj instanceof ResolvedModuleRevision && ((ResolvedModuleRevision) obj).getId().equals(getId());
132129 }
133130
134131 public int hashCode() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 * since the resolve engine itself won't check the same exception is not thrown ad libitum
2525 * </p>
2626 */
27 @SuppressWarnings("serial")
2728 public class RestartResolveProcess extends ResolveProcessException {
2829
2930 public RestartResolveProcess(String message) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3737 * The associated visit nodes, per rootModuleConf Note that the value is a List, because a node
3838 * can be visited from several parents during the resolution process
3939 */
40 private Map visitNodes = new HashMap(); // Map (String rootModuleConf -> List(VisitNode))
40 private Map<String, List<VisitNode>> visitNodes = new HashMap<>();
4141
4242 public VisitData(IvyNode node) {
4343 this.node = node;
4848 getVisitNodes(rootModuleConf).add(node);
4949 }
5050
51 public List getVisitNodes(String rootModuleConf) {
52 List visits = (List) visitNodes.get(rootModuleConf);
51 public List<VisitNode> getVisitNodes(String rootModuleConf) {
52 List<VisitNode> visits = visitNodes.get(rootModuleConf);
5353 if (visits == null) {
54 visits = new ArrayList();
54 visits = new ArrayList<>();
5555 visitNodes.put(rootModuleConf, visits);
5656 }
5757 return visits;
6565 this.node = node;
6666 }
6767
68 public void addVisitNodes(String rootModuleConf, List visitNodes) {
68 public void addVisitNodes(String rootModuleConf, List<VisitNode> visitNodes) {
6969 getVisitNodes(rootModuleConf).addAll(visitNodes);
7070 }
7171 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.util.Collection;
2121 import java.util.Collections;
2222 import java.util.HashSet;
23 import java.util.Iterator;
2423 import java.util.LinkedHashSet;
2524 import java.util.List;
2625
3736 /**
3837 * A visit node is an object used to represent one visit from one parent on an {@link IvyNode} of
3938 * the dependency graph. During dependency resolution, the {@link ResolveEngine} visits nodes of the
40 * depency graph following the dependencies, thus the same node can be visited several times, if it
41 * is requested from several module. In this case you will have one VisitNode per parent and per
39 * dependency graph following the dependencies, thus the same node can be visited several times, if
40 * it is requested from several module. In this case you will have one VisitNode per parent and per
4241 * root module configuration. Thus VisitNode stores data specific to the visit:
43 * <ul>
44 * <li>parent</li>
45 * the node from which the visit is occuring
46 * <li>parentConf</li>
47 * the configuration of the parent in which this node is visited
48 * <li>rootModuleConf</li>
49 * the configuration of the root module which is currently resolved
50 * </ul>
42 * <dl>
43 * <dd>parent</dd><dt>the node from which the visit is occurring</dt>
44 * <dd>parentConf</dd><dt>the configuration of the parent in which this node is visited</dt>
45 * <dd>rootModuleConf</dd><dt>the configuration of the root module which is currently resolved</dt>
46 * </dl>
5147 */
5248 public class VisitNode {
5349 /**
6662 private VisitNode root = null;
6763
6864 /**
69 * Direct path from root to this node. Note that the colleciton is ordered but is not a list
65 * Direct path from root to this node. Note that the collection is ordered but is not a list
7066 * implementation This collection is null until it is required, see getPath
7167 */
72 private Collection path = null; // Collection(VisitNode)
68 private Collection<VisitNode> path = null;
7369
7470 /**
7571 * The configuration of the parent module in the current visit
155151
156152 /**
157153 * Get an ordered collection with the nodes from the root to this node
158 *
159 * @return
160 */
161 public Collection/* <VisitNode> */getPath() {
154 *
155 * @return Collection&lt;VisitNode&gt;
156 */
157 public Collection<VisitNode> getPath() {
162158 if (path == null) {
163159 path = computePath();
164160 }
165161 return path;
166162 }
167163
168 private Collection/* <VisitNode> */computePath() {
164 private Collection<VisitNode> computePath() {
169165 if (parent != null) {
170 Collection p = new LinkedHashSet(parent.getPath());
166 Collection<VisitNode> p = new LinkedHashSet<>(parent.getPath());
171167 p.add(this);
172168 return p;
173169 } else {
199195
200196 public static VisitNode getRoot(VisitNode parent) {
201197 VisitNode root = parent;
202 Collection path = new HashSet();
198 Collection<VisitNode> path = new HashSet<>();
203199 path.add(root);
204200 while (root.getParent() != null && !root.getNode().isRoot()) {
205201 if (path.contains(root.getParent())) {
214210 /**
215211 * Returns true if the current dependency descriptor is transitive and the parent configuration
216212 * is transitive. Otherwise returns false.
217 *
213 *
218214 * @return true if current node is transitive and the parent configuration is transitive.
219215 */
220216 public boolean isTransitive() {
232228 }
233229
234230 DependencyDescriptor dd = node.getDependencyDescriptor(getParentNode());
235 if ((dd != null) && dd.isTransitive()) {
236 return true;
237 }
238
239 return node.hasAnyMergedUsageWithTransitiveDependency(rootModuleConf);
231 return (dd != null) && dd.isTransitive()
232 || node.hasAnyMergedUsageWithTransitiveDependency(rootModuleConf);
233
240234 }
241235
242236 /**
243237 * Checks if the current node's parent configuration is transitive.
244 *
245 * @param node
246 * current node
238 *
247239 * @return true if the node's parent configuration is transitive
248240 */
249241 protected boolean isParentConfTransitive() {
262254 * resolved to an existing node in the graph, we will return the existing node, and not the one
263255 * originally used which is about to be discarded, since it's not possible to have in the graph
264256 * two nodes for the same ModuleRevisionId
265 *
257 *
266258 * @return the 'real' node currently visited.
267259 */
268260 public IvyNode getRealNode() {
308300 return loaded;
309301 }
310302
311 public Collection/* <VisitNode> */getDependencies(String conf) {
312 Collection/* <IvyNode> */deps = node.getDependencies(rootModuleConf, conf, requestedConf);
313 Collection/* <VisitNode> */ret = new ArrayList(deps.size());
314 for (Iterator iter = deps.iterator(); iter.hasNext();) {
315 IvyNode depNode = (IvyNode) iter.next();
303 public Collection<VisitNode> getDependencies(String conf) {
304 Collection<IvyNode> deps = node.getDependencies(rootModuleConf, conf, requestedConf);
305 Collection<VisitNode> ret = new ArrayList<>(deps.size());
306 for (IvyNode depNode : deps) {
316307 ret.add(traverseChild(conf, depNode));
317308 }
318309 return ret;
321312 /**
322313 * Returns a VisitNode for the given node. The given node must be a representation of the same
323314 * module (usually in another revision) as the one visited by this node.
324 *
315 *
325316 * @param node
326317 * the node to visit
327318 * @return a VisitNode for the given node
335326 }
336327 VisitData visitData = data.getVisitData(node.getId());
337328 if (visitData != null) {
338 List visitNodes = visitData.getVisitNodes(rootModuleConf);
339 for (Iterator iter = visitNodes.iterator(); iter.hasNext();) {
340 VisitNode vnode = (VisitNode) iter.next();
329 List<VisitNode> visitNodes = visitData.getVisitNodes(rootModuleConf);
330 for (VisitNode vnode : visitNodes) {
341331 if ((parent == null && vnode.getParent() == null)
342332 || (parent != null && parent.getId().equals(vnode.getParent().getId()))) {
343333 vnode.parentConf = parentConf;
370360 return new VisitNode(data, node, parent, rootModuleConf, parentConf, usage);
371361 }
372362
373 private ModuleRevisionId[] toMrids(Collection path, ModuleRevisionId last) {
363 private ModuleRevisionId[] toMrids(Collection<VisitNode> path, ModuleRevisionId last) {
374364 ModuleRevisionId[] ret = new ModuleRevisionId[path.size() + 1];
375365 int i = 0;
376 for (Iterator iter = path.iterator(); iter.hasNext(); i++) {
377 VisitNode node = (VisitNode) iter.next();
366 for (VisitNode node : path) {
378367 ret[i] = node.getNode().getId();
379368 }
380369 ret[ret.length - 1] = last;
385374 return node.getResolvedId();
386375 }
387376
388 public void updateConfsToFetch(Collection confs) {
377 public void updateConfsToFetch(Collection<String> confs) {
389378 node.updateConfsToFetch(confs);
390379 }
391380
423412
424413 /**
425414 * Returns true if this node can already be found in the path
426 *
427 * @return
415 *
416 * @return boolean
428417 */
429418 public boolean isCircular() {
430419 if (isCircular == null) {
431420 if (parent != null) {
432 isCircular = Boolean.FALSE; // asumme it's false, and see if it isn't by checking
421 isCircular = Boolean.FALSE; // assume it's false, and see if it isn't by checking
433422 // the parent path
434 for (Iterator iter = parent.getPath().iterator(); iter.hasNext();) {
435 VisitNode ancestor = (VisitNode) iter.next();
423 for (VisitNode ancestor : parent.getPath()) {
436424 if (getId().getModuleId().equals(ancestor.getId().getModuleId())) {
437425 isCircular = Boolean.TRUE;
438426 break;
442430 isCircular = Boolean.FALSE;
443431 }
444432 }
445 return isCircular.booleanValue();
433 return isCircular;
446434 }
447435
448436 public String[] getConfsToFetch() {
457445 return node.getModuleId();
458446 }
459447
460 public Collection getResolvedRevisions(ModuleId mid) {
448 public Collection<ModuleRevisionId> getResolvedRevisions(ModuleId mid) {
461449 return node.getResolvedRevisions(mid, rootModuleConf);
462450 }
463451
472460 /**
473461 * Marks the current node as evicted by the the given selected IvyNodes, in the given parent and
474462 * root module configuration, with the given {@link ConflictManager}
475 *
463 *
476464 * @param parent
477465 * the VisitNode in which eviction has been made
478466 * @param conflictMgr
480468 * @param selected
481469 * a Collection of {@link IvyNode} which have been selected
482470 */
483 public void markEvicted(VisitNode parent, ConflictManager conflictMgr, Collection selected) {
471 public void markEvicted(VisitNode parent, ConflictManager conflictMgr,
472 Collection<IvyNode> selected) {
484473 node.markEvicted(rootModuleConf, parent.getNode(), conflictMgr, selected);
485474 }
486475
492481 return node.getEvictionDataInRoot(rootModuleConf, ancestor.getNode());
493482 }
494483
495 public Collection getEvictedRevisions(ModuleId moduleId) {
484 public Collection<ModuleRevisionId> getEvictedRevisions(ModuleId moduleId) {
496485 return node.getEvictedRevisions(moduleId, rootModuleConf);
497486 }
498487
507496 // rootModuleConf = rootModuleConf;
508497 // }
509498
499 @Override
510500 public String toString() {
511501 return node.toString();
512502 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import java.util.Comparator;
2727 import java.util.HashMap;
2828 import java.util.HashSet;
29 import java.util.Iterator;
3029 import java.util.List;
3130 import java.util.Map;
3231 import java.util.Set;
4241 import org.apache.ivy.core.event.retrieve.StartRetrieveEvent;
4342 import org.apache.ivy.core.module.descriptor.Artifact;
4443 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
44 import org.apache.ivy.core.module.id.ArtifactRevisionId;
4545 import org.apache.ivy.core.module.id.ModuleId;
4646 import org.apache.ivy.core.module.id.ModuleRevisionId;
47 import org.apache.ivy.core.pack.PackagingManager;
4748 import org.apache.ivy.core.report.ArtifactDownloadReport;
4849 import org.apache.ivy.core.resolve.ResolveOptions;
4950 import org.apache.ivy.plugins.report.XmlReportParser;
6869 * localCacheDirectory to determine an ivy report file, used as input for the copy If such a
6970 * file does not exist for any conf (resolve has not been called before ?) then an
7071 * IllegalStateException is thrown and nothing is copied.
71 *
72 *
73 * @param mrid ModuleRevisionId
74 * @param destFilePattern String
75 * @param options RetrieveOptions
76 * @return int
77 * @throws IOException if something goes wrong
7278 * @deprecated Use
7379 * {@link #retrieve(org.apache.ivy.core.module.id.ModuleRevisionId, RetrieveOptions)}
7480 * instead
7682 @Deprecated
7783 public int retrieve(ModuleRevisionId mrid, String destFilePattern, RetrieveOptions options)
7884 throws IOException {
79 RetrieveOptions retieveOptions = new RetrieveOptions(options);
80 retieveOptions.setDestArtifactPattern(destFilePattern);
81
82 RetrieveReport result = retrieve(mrid, retieveOptions);
85 RetrieveOptions retrieveOptions = new RetrieveOptions(options);
86 retrieveOptions.setDestArtifactPattern(destFilePattern);
87
88 RetrieveReport result = retrieve(mrid, retrieveOptions);
8389 return result.getNbrArtifactsCopied();
8490 }
8591
112118 }
113119
114120 try {
115 Map/* <File, File> */destToSrcMap = null;
116 // Map<ArtifactDownloadReport, Set<String>>
117 Map artifactsToCopy = determineArtifactsToCopy(mrid, destFilePattern, options);
121 Map<ArtifactDownloadReport, Set<String>> artifactsToCopy = determineArtifactsToCopy(
122 mrid, destFilePattern, options);
118123 File fileRetrieveRoot = settings.resolveFile(IvyPatternHelper
119124 .getTokenRoot(destFilePattern));
120125 report.setRetrieveRoot(fileRetrieveRoot);
121126 File ivyRetrieveRoot = destIvyPattern == null ? null : settings
122127 .resolveFile(IvyPatternHelper.getTokenRoot(destIvyPattern));
123 Collection targetArtifactsStructure = new HashSet(); // Set(File) set of all paths
124 // which should be present at
125 // then end of retrieve (useful
128 Collection<File> targetArtifactsStructure = new HashSet<>();
129 // Set(File) set of all paths which should be present at then end of retrieve (useful
126130 // for sync)
127 Collection targetIvysStructure = new HashSet(); // same for ivy files
128
129 if (options.isMakeSymlinksInMass()) {
130 // The HashMap is of "destToSrc" because src could go two places, but dest can only
131 // come from one
132 destToSrcMap = new HashMap();
133 }
131 Collection<File> targetIvysStructure = new HashSet<>(); // same for ivy files
134132
135133 // do retrieve
136134 long totalCopiedSize = 0;
137 for (Iterator iter = artifactsToCopy.keySet().iterator(); iter.hasNext();) {
138 ArtifactDownloadReport artifact = (ArtifactDownloadReport) iter.next();
135 for (Map.Entry<ArtifactDownloadReport, Set<String>> artifactAndPaths : artifactsToCopy
136 .entrySet()) {
137 ArtifactDownloadReport artifact = artifactAndPaths.getKey();
139138 File archive = artifact.getLocalFile();
140139 if (artifact.getUnpackedLocalFile() != null) {
141140 archive = artifact.getUnpackedLocalFile();
144143 Message.verbose("\tno local file available for " + artifact + ": skipping");
145144 continue;
146145 }
147 Set dest = (Set) artifactsToCopy.get(artifact);
148146 Message.verbose("\tretrieving " + archive);
149 for (Iterator it2 = dest.iterator(); it2.hasNext();) {
147 for (String path : artifactAndPaths.getValue()) {
150148 IvyContext.getContext().checkInterrupted();
151 File destFile = settings.resolveFile((String) it2.next());
149 File destFile = settings.resolveFile(path);
152150 if (!settings.isCheckUpToDate() || !upToDate(archive, destFile, options)) {
153151 Message.verbose("\t\tto " + destFile);
154152 if (this.eventManager != null) {
155 // There is no unitary event for the mass sym linking.
156 // skip the event declaration.
157 if (!options.isMakeSymlinksInMass()) {
158 this.eventManager.fireIvyEvent(new StartRetrieveArtifactEvent(
159 artifact, destFile));
153 this.eventManager.fireIvyEvent(new StartRetrieveArtifactEvent(artifact, destFile));
154 }
155 if (options.isMakeSymlinks()) {
156 boolean symlinkCreated;
157 try {
158 symlinkCreated = FileUtil.symlink(archive, destFile, true);
159 } catch (IOException ioe) {
160 symlinkCreated = false;
161 // warn about the inability to create a symlink
162 Message.warn("symlink creation failed at path " + destFile, ioe);
160163 }
161 }
162 if (options.isMakeSymlinksInMass()) {
163 if (FileUtil.prepareCopy(archive, destFile, true)) {
164 destToSrcMap.put(destFile, archive);
164 if (!symlinkCreated) {
165 // since symlink creation failed, let's attempt to an actual copy instead
166 Message.info("Attempting a copy operation (since symlink creation failed) at path " + destFile);
167 FileUtil.copy(archive, destFile, null, true);
165168 }
166 } else if (options.isMakeSymlinks()) {
167 FileUtil.symlink(archive, destFile, null, true);
168169 } else {
169170 FileUtil.copy(archive, destFile, null, true);
170171 }
171172 if (this.eventManager != null) {
172 // There is no unitary event for the mass sym linking.
173 // skip the event declaration.
174 if (!options.isMakeSymlinksInMass()) {
175 this.eventManager.fireIvyEvent(new EndRetrieveArtifactEvent(
176 artifact, destFile));
177 }
173 this.eventManager.fireIvyEvent(new EndRetrieveArtifactEvent(artifact, destFile));
178174 }
179175 totalCopiedSize += FileUtil.getFileLength(destFile);
180176 report.addCopiedFile(destFile, artifact);
187183 targetIvysStructure
188184 .addAll(FileUtil.getPathFiles(ivyRetrieveRoot, destFile));
189185 } else {
190 Iterator destFiles = FileUtil.listAll(destFile, Collections.EMPTY_LIST)
191 .iterator();
192 while (destFiles.hasNext()) {
186 Collection<File> files = FileUtil.listAll(destFile,
187 Collections.<String> emptyList());
188 for (File file : files) {
193189 targetArtifactsStructure.addAll(FileUtil.getPathFiles(fileRetrieveRoot,
194 (File) destFiles.next()));
190 file));
195191 }
196192 }
197193 }
198 }
199
200 if (options.isMakeSymlinksInMass()) {
201 Message.verbose("\tMass symlinking " + destToSrcMap.size() + " files");
202 FileUtil.symlinkInMass(destToSrcMap, true);
203194 }
204195
205196 if (options.isSync()) {
206197 Message.verbose("\tsyncing...");
207198
208199 String[] ignorableFilenames = settings.getIgnorableFilenames();
209 Collection ignoreList = Arrays.asList(ignorableFilenames);
210
211 Collection existingArtifacts = FileUtil.listAll(fileRetrieveRoot, ignoreList);
212 Collection existingIvys = ivyRetrieveRoot == null ? null : FileUtil.listAll(
200 Collection<String> ignoreList = Arrays.asList(ignorableFilenames);
201
202 Collection<File> existingArtifacts = FileUtil.listAll(fileRetrieveRoot, ignoreList);
203 Collection<File> existingIvys = (ivyRetrieveRoot == null) ? null : FileUtil.listAll(
213204 ivyRetrieveRoot, ignoreList);
214205
215206 if (fileRetrieveRoot.equals(ivyRetrieveRoot)) {
216 Collection target = targetArtifactsStructure;
217 target.addAll(targetIvysStructure);
218 Collection existing = existingArtifacts;
219 existing.addAll(existingIvys);
220 sync(target, existing);
207 targetArtifactsStructure.addAll(targetIvysStructure);
208 existingArtifacts.addAll(existingIvys);
209 sync(targetArtifactsStructure, existingArtifacts);
221210 } else {
222211 sync(targetArtifactsStructure, existingArtifacts);
223212 if (existingIvys != null) {
261250 } catch (IOException e) {
262251 throw e;
263252 } catch (Exception e) {
264 IOException ioex = new IOException(e.getMessage());
265 ioex.initCause(e);
266 throw ioex;
253 throw new IOException(e.getMessage(), e);
267254 }
268255 }
269256 return confs;
273260 return settings.getResolutionCacheManager();
274261 }
275262
276 private void sync(Collection target, Collection existing) {
277 Collection toRemove = new HashSet();
278 for (Iterator iter = existing.iterator(); iter.hasNext();) {
279 File file = (File) iter.next();
263 private void sync(Collection<File> target, Collection<File> existing) {
264 Collection<File> toRemove = new HashSet<>();
265 for (File file : existing) {
280266 toRemove.add(file.getAbsoluteFile());
281267 }
282 for (Iterator iter = target.iterator(); iter.hasNext();) {
283 File file = (File) iter.next();
268 for (File file : target) {
284269 toRemove.remove(file.getAbsoluteFile());
285270 }
286 for (Iterator iter = toRemove.iterator(); iter.hasNext();) {
287 File file = (File) iter.next();
271 for (File file : toRemove) {
288272 if (file.exists()) {
289273 Message.verbose("\t\tdeleting " + file);
290274 FileUtil.forceDelete(file);
292276 }
293277 }
294278
295 /**
296 * @return Map<ArtifactDownloadReport, Set<String>>
297 */
298 public Map determineArtifactsToCopy(ModuleRevisionId mrid, String destFilePattern,
299 RetrieveOptions options) throws ParseException, IOException {
279 public Map<ArtifactDownloadReport, Set<String>> determineArtifactsToCopy(ModuleRevisionId mrid,
280 String destFilePattern, RetrieveOptions options) throws ParseException, IOException {
300281 ModuleId moduleId = mrid.getModuleId();
301282
302283 if (options.getResolveId() == null) {
311292 // find what we must retrieve where
312293
313294 // ArtifactDownloadReport source -> Set (String copyDestAbsolutePath)
314 final Map artifactsToCopy = new HashMap();
295 final Map<ArtifactDownloadReport, Set<String>> artifactsToCopy = new HashMap<>();
315296 // String copyDestAbsolutePath -> Set (ArtifactRevisionId source)
316 final Map conflictsMap = new HashMap();
297 final Map<String, Set<ArtifactRevisionId>> conflictsMap = new HashMap<>();
317298 // String copyDestAbsolutePath -> Set (ArtifactDownloadReport source)
318 final Map conflictsReportsMap = new HashMap();
299 final Map<String, Set<ArtifactDownloadReport>> conflictsReportsMap = new HashMap<>();
319300 // String copyDestAbsolutePath -> Set (String conf)
320 final Map conflictsConfMap = new HashMap();
301 final Map<String, Set<String>> conflictsConfMap = new HashMap<>();
321302
322303 XmlReportParser parser = new XmlReportParser();
323 for (int i = 0; i < confs.length; i++) {
324 final String conf = confs[i];
325
304 for (final String conf : confs) {
326305 File report = cacheManager.getConfigurationResolveReportInCache(options.getResolveId(),
327306 conf);
328307 parser.parse(report);
329308
330 Collection artifacts = new ArrayList(Arrays.asList(parser.getArtifactReports()));
309 Collection<ArtifactDownloadReport> artifacts = new ArrayList<>(
310 Arrays.asList(parser.getArtifactReports()));
331311 if (destIvyPattern != null) {
332 ModuleRevisionId[] mrids = parser.getRealDependencyRevisionIds();
333 for (int j = 0; j < mrids.length; j++) {
334 artifacts.add(parser.getMetadataArtifactReport(mrids[j]));
335 }
336 }
337 for (Iterator iter = artifacts.iterator(); iter.hasNext();) {
338 ArtifactDownloadReport adr = (ArtifactDownloadReport) iter.next();
339
340 Artifact artifact = adr.getArtifact();
341 String ext = artifact.getExt();
342 if (adr.getUnpackedLocalFile() != null) {
343 ext = "";
312 for (ModuleRevisionId rmrid : parser.getRealDependencyRevisionIds()) {
313 artifacts.add(parser.getMetadataArtifactReport(rmrid));
314 }
315 }
316 final PackagingManager packagingManager = new PackagingManager();
317 packagingManager.setSettings(IvyContext.getContext().getSettings());
318
319 for (final ArtifactDownloadReport adr : artifacts) {
320
321 final Artifact artifact = adr.getArtifact();
322 final String ext;
323 if (adr.getUnpackedLocalFile() == null) {
324 ext = artifact.getExt();
325 } else {
326 final Artifact unpackedArtifact;
327 // check if the download report is aware of the unpacked artifact
328 if (adr.getUnpackedArtifact() != null) {
329 unpackedArtifact = adr.getUnpackedArtifact();
330 } else {
331 // use the packaging manager to get hold of the unpacked artifact
332 unpackedArtifact = packagingManager.getUnpackedArtifact(artifact);
333 }
334 if (unpackedArtifact == null) {
335 throw new RuntimeException("Could not determine unpacked artifact for " + artifact
336 + " while determining artifacts to copy for module " + mrid);
337 }
338 ext = unpackedArtifact.getExt();
344339 }
345340
346341 String destPattern = "ivy".equals(adr.getType()) ? destIvyPattern : destFilePattern;
356351 aMrid.getRevision(), artifact.getName(), artifact.getType(), ext, conf,
357352 adr.getArtifactOrigin(), aMrid.getQualifiedExtraAttributes(),
358353 artifact.getQualifiedExtraAttributes());
359 Set dest = (Set) artifactsToCopy.get(adr);
354 Set<String> dest = artifactsToCopy.get(adr);
360355 if (dest == null) {
361 dest = new HashSet();
356 dest = new HashSet<>();
362357 artifactsToCopy.put(adr, dest);
363358 }
364359 String copyDest = settings.resolveFile(destFileName).getAbsolutePath();
368363 destinations = options.getMapper().mapFileName(copyDest);
369364 }
370365
371 for (int j = 0; j < destinations.length; j++) {
372 dest.add(destinations[j]);
373
374 Set conflicts = (Set) conflictsMap.get(destinations[j]);
375 Set conflictsReports = (Set) conflictsReportsMap.get(destinations[j]);
376 Set conflictsConf = (Set) conflictsConfMap.get(destinations[j]);
366 for (String destination : destinations) {
367 dest.add(destination);
368
369 Set<ArtifactRevisionId> conflicts = conflictsMap.get(destination);
370 Set<ArtifactDownloadReport> conflictsReports = conflictsReportsMap
371 .get(destination);
372 Set<String> conflictsConf = conflictsConfMap.get(destination);
377373 if (conflicts == null) {
378 conflicts = new HashSet();
379 conflictsMap.put(destinations[j], conflicts);
374 conflicts = new HashSet<>();
375 conflictsMap.put(destination, conflicts);
380376 }
381377 if (conflictsReports == null) {
382 conflictsReports = new HashSet();
383 conflictsReportsMap.put(destinations[j], conflictsReports);
378 conflictsReports = new HashSet<>();
379 conflictsReportsMap.put(destination, conflictsReports);
384380 }
385381 if (conflictsConf == null) {
386 conflictsConf = new HashSet();
387 conflictsConfMap.put(destinations[j], conflictsConf);
382 conflictsConf = new HashSet<>();
383 conflictsConfMap.put(destination, conflictsConf);
388384 }
389385 if (conflicts.add(artifact.getId())) {
390386 conflictsReports.add(adr);
395391 }
396392
397393 // resolve conflicts if any
398 for (Iterator iter = conflictsMap.keySet().iterator(); iter.hasNext();) {
399 String copyDest = (String) iter.next();
400 Set artifacts = (Set) conflictsMap.get(copyDest);
401 Set conflictsConfs = (Set) conflictsConfMap.get(copyDest);
394 for (Map.Entry<String, Set<ArtifactRevisionId>> entry : conflictsMap.entrySet()) {
395 String copyDest = entry.getKey();
396 Set<ArtifactRevisionId> artifacts = entry.getValue();
397 Set<String> conflictsConfs = conflictsConfMap.get(copyDest);
402398 if (artifacts.size() > 1) {
403 List artifactsList = new ArrayList((Collection) conflictsReportsMap.get(copyDest));
399 List<ArtifactDownloadReport> artifactsList = new ArrayList<>(
400 conflictsReportsMap.get(copyDest));
404401 // conflicts battle is resolved by a sort using a conflict resolving policy
405402 // comparator which consider as greater a winning artifact
406403 Collections.sort(artifactsList, getConflictResolvingPolicy());
407404
408405 // after the sort, the winning artifact is the greatest one, i.e. the last one
409406 // we fail if different artifacts of the same module are mapped to the same file
410 ArtifactDownloadReport winner = (ArtifactDownloadReport) artifactsList
411 .get(artifactsList.size() - 1);
407 ArtifactDownloadReport winner = artifactsList.get(artifactsList.size() - 1);
412408 ModuleRevisionId winnerMD = winner.getArtifact().getModuleRevisionId();
413409 for (int i = artifactsList.size() - 2; i >= 0; i--) {
414 ArtifactDownloadReport current = (ArtifactDownloadReport) artifactsList.get(i);
410 ArtifactDownloadReport current = artifactsList.get(i);
415411 if (winnerMD.equals(current.getArtifact().getModuleRevisionId())) {
416412 throw new RuntimeException("Multiple artifacts of the module " + winnerMD
417413 + " are retrieved to the same file! Update the retrieve pattern "
425421 // we now iterate over the list beginning with the artifact preceding the winner,
426422 // and going backward to the least artifact
427423 for (int i = artifactsList.size() - 2; i >= 0; i--) {
428 ArtifactDownloadReport looser = (ArtifactDownloadReport) artifactsList.get(i);
424 ArtifactDownloadReport looser = artifactsList.get(i);
429425 Message.verbose("\t\tremoving conflict looser artifact: "
430426 + looser.getArtifact());
431427 // for each loser, we remove the pair (loser - copyDest) in the artifactsToCopy
432428 // map
433 Set dest = (Set) artifactsToCopy.get(looser);
429 Set<String> dest = artifactsToCopy.get(looser);
434430 dest.remove(copyDest);
435431 if (dest.isEmpty()) {
436432 artifactsToCopy.remove(looser);
470466 /**
471467 * The returned comparator should consider greater the artifact which gains the conflict battle.
472468 * This is used only during retrieve... prefer resolve conflict manager to resolve conflicts.
473 *
474 * @return
469 *
470 * @return Comparator&lt;ArtifactDownloadReport&gt;
475471 */
476 private Comparator getConflictResolvingPolicy() {
477 return new Comparator() {
472 private Comparator<ArtifactDownloadReport> getConflictResolvingPolicy() {
473 return new Comparator<ArtifactDownloadReport>() {
478474 // younger conflict resolving policy
479 public int compare(Object o1, Object o2) {
480 Artifact a1 = ((ArtifactDownloadReport) o1).getArtifact();
481 Artifact a2 = ((ArtifactDownloadReport) o2).getArtifact();
475 public int compare(ArtifactDownloadReport o1, ArtifactDownloadReport o2) {
476 Artifact a1 = o1.getArtifact();
477 Artifact a2 = o2.getArtifact();
482478 if (a1.getPublicationDate().after(a2.getPublicationDate())) {
483479 // a1 is after a2 <=> a1 is younger than a2 <=> a1 wins the conflict battle
484480 return +1;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.core.retrieve;
1818
1919 import org.apache.ivy.core.LogOptions;
20 import org.apache.ivy.core.module.descriptor.Artifact;
21 import org.apache.ivy.util.Message;
2022 import org.apache.ivy.util.filter.Filter;
2123 import org.apache.ivy.util.filter.FilterHelper;
2224
2325 /**
2426 * A set of options used during retrieve related tasks
25 *
27 *
2628 * @see RetrieveEngine
2729 */
2830 public class RetrieveOptions extends LogOptions {
5456 /**
5557 * The filter to apply before retrieving artifacts.
5658 */
57 private Filter artifactFilter = FilterHelper.NO_FILTER;
58
59 /**
60 * True if a synchronisation of the destination directory should be done, false if a simple copy
61 * is enough. Synchronisation means that after the retrieve only files which have been retrieved
62 * will be present in the destination directory, which means that some files may be deleted.
59 private Filter<Artifact> artifactFilter = FilterHelper.NO_FILTER;
60
61 /**
62 * True if a synchronisation of the destination directory should be done, false if a simple
63 * copy is enough. Synchronisation means that after the retrieve only files which have been
64 * retrieved will be present in the destination directory, which means that some files may be
65 * deleted.
6366 */
6467 private boolean sync = false;
6568
6669 private String overwriteMode = OVERWRITEMODE_NEWER;
6770
6871 /**
69 * True if the original files should be used insteaad of their cache copy.
72 * True if the original files should be used instead of their cache copy.
7073 */
7174 private boolean useOrigin = false;
7275
7679 */
7780 private boolean makeSymlinks = false;
7881
79 /**
80 * True if symbolic links should be created all at once, instead of one at a time. Works only on
81 * OS supporting with both "sh" (a shell) and "ln" (the link command).
82 */
82 @Deprecated
8383 private boolean makeSymlinksInMass = false;
8484
8585 /**
116116 return this;
117117 }
118118
119 public Filter getArtifactFilter() {
119 public Filter<Artifact> getArtifactFilter() {
120120 return artifactFilter;
121121 }
122122
123 public RetrieveOptions setArtifactFilter(Filter artifactFilter) {
123 public RetrieveOptions setArtifactFilter(Filter<Artifact> artifactFilter) {
124124 this.artifactFilter = artifactFilter;
125125 return this;
126126 }
153153 }
154154
155155 public boolean isMakeSymlinks() {
156 return makeSymlinks;
157 }
158
156 // we also do a check on makeSymlinkInMass just to allow backward compatibility for
157 // a version or so, to allow users time to move away from symlinkmass option
158 return makeSymlinks || makeSymlinksInMass;
159 }
160
161 /**
162 * @return false
163 * @deprecated Starting 2.5, creating symlinks in mass is no longer supported and this
164 * method will always return false
165 */
166 @Deprecated
159167 public boolean isMakeSymlinksInMass() {
160 return makeSymlinksInMass;
168 return false;
161169 }
162170
163171 public RetrieveOptions setMakeSymlinks(boolean makeSymlinks) {
165173 return this;
166174 }
167175
176 /**
177 * @param makeSymlinksInMass ditto
178 * @return RetrieveOptions
179 * @deprecated Starting 2.5, creating symlinks in mass is no longer supported and this
180 * method plays no role in creation of symlinks. Use {@link #setMakeSymlinks(boolean)} instead
181 */
182 @Deprecated
168183 public RetrieveOptions setMakeSymlinksInMass(boolean makeSymlinksInMass) {
169184 this.makeSymlinksInMass = makeSymlinksInMass;
185 Message.warn("symlinkmass option has been deprecated and will no longer be supported");
170186 return this;
171187 }
172188
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727
2828 public class RetrieveReport {
2929
30 private Collection/* <File> */upToDateFiles = new HashSet();
30 private Collection<File> upToDateFiles = new HashSet<>();
3131
32 private Collection/* <File> */copiedFiles = new HashSet();
32 private Collection<File> copiedFiles = new HashSet<>();
3333
34 private Map/* <File, ArtifactDownloadReport> */downloadReport = new HashMap();
34 private Map<File, ArtifactDownloadReport> downloadReport = new HashMap<>();
3535
3636 private File retrieveRoot;
3737
3838 /**
3939 * Returns the root directory to where the artifacts are retrieved.
40 *
41 * @return File
4042 */
4143 public File getRetrieveRoot() {
4244 return retrieveRoot;
6769 /**
6870 * Returns a collection of <tt>File</tt> objects who were actually copied during the retrieve
6971 * process.
72 *
73 * @return Collection&lt;File&gt;
7074 */
71 public Collection getCopiedFiles() {
72 return new ArrayList(copiedFiles);
75 public Collection<File> getCopiedFiles() {
76 return new ArrayList<>(copiedFiles);
7377 }
7478
7579 /**
7680 * Returns a collection of <tt>File</tt> objects who were actually copied during the retrieve
7781 * process.
82 *
83 * @return Collection&lt;File&gt;
7884 */
79 public Collection getUpToDateFiles() {
80 return new ArrayList(upToDateFiles);
85 public Collection<File> getUpToDateFiles() {
86 return new ArrayList<>(upToDateFiles);
8187 }
8288
8389 /**
8490 * Returns a collection of <tt>File</tt> objects who were retrieved during the retrieve process.
8591 * This is the union of the files being copied and the files that were up-to-date.
92 *
93 * @return Collection&lt;File&gt;
8694 */
87 public Collection getRetrievedFiles() {
88 Collection result = new ArrayList(upToDateFiles.size() + copiedFiles.size());
95 public Collection<File> getRetrievedFiles() {
96 Collection<File> result = new ArrayList<>(upToDateFiles.size() + copiedFiles.size());
8997 result.addAll(upToDateFiles);
9098 result.addAll(copiedFiles);
9199 return result;
93101
94102 /**
95103 * Get the mapping between the copied files and their corresponding download report
104 *
105 * @return Map&lt;File,ArtifactDownloadReport&gt;
96106 */
97 public Map getDownloadReport() {
107 public Map<File, ArtifactDownloadReport> getDownloadReport() {
98108 return downloadReport;
99109 }
100110 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.Collection;
2222 import java.util.HashMap;
2323 import java.util.HashSet;
24 import java.util.Iterator;
2524 import java.util.LinkedHashSet;
2625 import java.util.List;
2726 import java.util.Map;
28 import java.util.Map.Entry;
2927 import java.util.Set;
3028
3129 import org.apache.ivy.core.IvyPatternHelper;
5048
5149 /**
5250 * Returns an empty array when no token values are found.
53 *
51 *
5452 * @param token
55 * @param otherTokenValues
56 * @return
53 * ditto
54 * @param otherTokenValues Map
55 * @return String[]
5756 */
58 public String[] listTokenValues(String token, Map otherTokenValues) {
59 Set entries = new LinkedHashSet();
60
61 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
62 DependencyResolver resolver = (DependencyResolver) iter.next();
63 Map[] values = resolver.listTokenValues(new String[] {token}, otherTokenValues);
64 for (int i = 0; i < values.length; i++) {
65 entries.add(values[i].get(token));
66 }
67 }
68
69 return (String[]) entries.toArray(new String[entries.size()]);
57 public String[] listTokenValues(String token, Map<String, Object> otherTokenValues) {
58 Set<String> entries = new LinkedHashSet<>();
59
60 for (DependencyResolver resolver : settings.getResolvers()) {
61 Map<String, String>[] values = resolver.listTokenValues(new String[] {token},
62 otherTokenValues);
63 for (Map<String, String> value : values) {
64 entries.add(value.get(token));
65 }
66 }
67
68 return entries.toArray(new String[entries.size()]);
7069 }
7170
7271 public OrganisationEntry[] listOrganisationEntries() {
73 Set entries = new HashSet();
74
75 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
76 DependencyResolver resolver = (DependencyResolver) iter.next();
77 Map[] orgs = resolver.listTokenValues(new String[] {IvyPatternHelper.ORGANISATION_KEY},
78 new HashMap());
79 for (int i = 0; i < orgs.length; i++) {
80 String org = (String) orgs[i].get(IvyPatternHelper.ORGANISATION_KEY);
72 Set<OrganisationEntry> entries = new HashSet<>();
73
74 for (DependencyResolver resolver : settings.getResolvers()) {
75 Map<String, String>[] orgs = resolver.listTokenValues(
76 new String[] {IvyPatternHelper.ORGANISATION_KEY}, new HashMap<String, Object>());
77 for (Map<String, String> oe : orgs) {
78 String org = oe.get(IvyPatternHelper.ORGANISATION_KEY);
8179 entries.add(new OrganisationEntry(resolver, org));
8280 }
8381 }
8482
85 return (OrganisationEntry[]) entries.toArray(new OrganisationEntry[entries.size()]);
83 return entries.toArray(new OrganisationEntry[entries.size()]);
8684 }
8785
8886 public String[] listOrganisations() {
89 Set entries = new HashSet();
90
91 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
92 DependencyResolver resolver = (DependencyResolver) iter.next();
93 Map[] orgs = resolver.listTokenValues(new String[] {IvyPatternHelper.ORGANISATION_KEY},
94 new HashMap());
95 for (int i = 0; i < orgs.length; i++) {
96 entries.add(orgs[i].get(IvyPatternHelper.ORGANISATION_KEY));
97 }
98 }
99
100 return (String[]) entries.toArray(new String[entries.size()]);
87 Set<String> entries = new HashSet<>();
88
89 for (DependencyResolver resolver : settings.getResolvers()) {
90 Map<String, String>[] orgs = resolver.listTokenValues(
91 new String[] {IvyPatternHelper.ORGANISATION_KEY}, new HashMap<String, Object>());
92 for (Map<String, String> org : orgs) {
93 entries.add(org.get(IvyPatternHelper.ORGANISATION_KEY));
94 }
95 }
96
97 return entries.toArray(new String[entries.size()]);
10198 }
10299
103100 public ModuleEntry[] listModuleEntries(OrganisationEntry org) {
104 Set entries = new HashSet();
105
106 Map tokenValues = new HashMap();
101 Set<ModuleEntry> entries = new HashSet<>();
102
103 Map<String, Object> tokenValues = new HashMap<>();
107104 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org.getOrganisation());
108105
109 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
110 DependencyResolver resolver = (DependencyResolver) iter.next();
111 Map[] modules = resolver.listTokenValues(new String[] {IvyPatternHelper.MODULE_KEY},
112 tokenValues);
113 for (int i = 0; i < modules.length; i++) {
114 String module = (String) modules[i].get(IvyPatternHelper.MODULE_KEY);
106 for (DependencyResolver resolver : settings.getResolvers()) {
107 Map<String, String>[] modules = resolver.listTokenValues(
108 new String[] {IvyPatternHelper.MODULE_KEY}, tokenValues);
109 for (Map<String, String> me : modules) {
110 String module = me.get(IvyPatternHelper.MODULE_KEY);
115111 entries.add(new ModuleEntry(org, module));
116112 }
117113 }
118114
119 return (ModuleEntry[]) entries.toArray(new ModuleEntry[entries.size()]);
115 return entries.toArray(new ModuleEntry[entries.size()]);
120116 }
121117
122118 public String[] listModules(String org) {
123 Set entries = new HashSet();
124
125 Map tokenValues = new HashMap();
119 Set<String> entries = new HashSet<>();
120
121 Map<String, Object> tokenValues = new HashMap<>();
126122 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org);
127123
128 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
129 DependencyResolver resolver = (DependencyResolver) iter.next();
130 Map[] modules = resolver.listTokenValues(new String[] {IvyPatternHelper.MODULE_KEY},
131 tokenValues);
132 for (int i = 0; i < modules.length; i++) {
133 entries.add(modules[i].get(IvyPatternHelper.MODULE_KEY));
134 }
135 }
136
137 return (String[]) entries.toArray(new String[entries.size()]);
124 for (DependencyResolver resolver : settings.getResolvers()) {
125 Map<String, String>[] modules = resolver.listTokenValues(
126 new String[] {IvyPatternHelper.MODULE_KEY}, tokenValues);
127 for (Map<String, String> module : modules) {
128 entries.add(module.get(IvyPatternHelper.MODULE_KEY));
129 }
130 }
131
132 return entries.toArray(new String[entries.size()]);
138133 }
139134
140135 public RevisionEntry[] listRevisionEntries(ModuleEntry module) {
141 Set entries = new HashSet();
142
143 Map tokenValues = new HashMap();
136 Set<RevisionEntry> entries = new HashSet<>();
137
138 Map<String, Object> tokenValues = new HashMap<>();
144139 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, module.getOrganisation());
145140 tokenValues.put(IvyPatternHelper.MODULE_KEY, module.getModule());
146141
147 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
148 DependencyResolver resolver = (DependencyResolver) iter.next();
149 Map[] revisions = resolver.listTokenValues(
142 for (DependencyResolver resolver : settings.getResolvers()) {
143 Map<String, String>[] revisions = resolver.listTokenValues(
150144 new String[] {IvyPatternHelper.REVISION_KEY}, tokenValues);
151 for (int i = 0; i < revisions.length; i++) {
152 String revision = (String) revisions[i].get(IvyPatternHelper.REVISION_KEY);
153 entries.add(new RevisionEntry(module, revision));
154 }
155 }
156
157 return (RevisionEntry[]) entries.toArray(new RevisionEntry[entries.size()]);
145 for (Map<String, String> revision : revisions) {
146 entries.add(new RevisionEntry(module, revision.get(IvyPatternHelper.REVISION_KEY)));
147 }
148 }
149
150 return entries.toArray(new RevisionEntry[entries.size()]);
158151 }
159152
160153 public String[] listRevisions(String org, String module) {
161 Set entries = new HashSet();
162
163 Map tokenValues = new HashMap();
154 Set<String> entries = new HashSet<>();
155
156 Map<String, Object> tokenValues = new HashMap<>();
164157 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org);
165158 tokenValues.put(IvyPatternHelper.MODULE_KEY, module);
166159
167 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
168 DependencyResolver resolver = (DependencyResolver) iter.next();
169 Map[] revisions = resolver.listTokenValues(
160 for (DependencyResolver resolver : settings.getResolvers()) {
161 Map<String, String>[] revisions = resolver.listTokenValues(
170162 new String[] {IvyPatternHelper.REVISION_KEY}, tokenValues);
171 for (int i = 0; i < revisions.length; i++) {
172 entries.add(revisions[i].get(IvyPatternHelper.REVISION_KEY));
173 }
174 }
175
176 return (String[]) entries.toArray(new String[entries.size()]);
163 for (Map<String, String> revision : revisions) {
164 entries.add(revision.get(IvyPatternHelper.REVISION_KEY));
165 }
166 }
167
168 return entries.toArray(new String[entries.size()]);
177169 }
178170
179171 /**
182174 * <p>
183175 * ModuleId are returned in the system namespace.
184176 * </p>
185 *
186 * @param criteria
187 * @param matcher
188 * @return
177 *
178 * @param moduleCrit ModuleId
179 * @param matcher PatternMatcher
180 * @return ModuleId[]
189181 */
190182 public ModuleId[] listModules(ModuleId moduleCrit, PatternMatcher matcher) {
191 List ret = new ArrayList();
192
193 Map criteria = new HashMap();
183 List<ModuleId> ret = new ArrayList<>();
184
185 Map<String, Object> criteria = new HashMap<>();
194186 addMatcher(matcher, moduleCrit.getOrganisation(), criteria,
195187 IvyPatternHelper.ORGANISATION_KEY);
196188 addMatcher(matcher, moduleCrit.getName(), criteria, IvyPatternHelper.MODULE_KEY);
198190 String[] tokensToList = new String[] {IvyPatternHelper.ORGANISATION_KEY,
199191 IvyPatternHelper.MODULE_KEY};
200192
201 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
202 DependencyResolver resolver = (DependencyResolver) iter.next();
203 Map[] moduleIdAsMap = resolver.listTokenValues(tokensToList, criteria);
204 for (int i = 0; i < moduleIdAsMap.length; i++) {
205 String org = (String) moduleIdAsMap[i].get(IvyPatternHelper.ORGANISATION_KEY);
206 String name = (String) moduleIdAsMap[i].get(IvyPatternHelper.MODULE_KEY);
193 for (DependencyResolver resolver : settings.getResolvers()) {
194 Map<String, String>[] moduleIdAsMap = resolver.listTokenValues(tokensToList, criteria);
195 for (Map<String, String> moduleId : moduleIdAsMap) {
196 String org = moduleId.get(IvyPatternHelper.ORGANISATION_KEY);
197 String name = moduleId.get(IvyPatternHelper.MODULE_KEY);
207198 ModuleId modId = ModuleId.newInstance(org, name);
208199 ret.add(NameSpaceHelper.transform(modId, resolver.getNamespace()
209200 .getToSystemTransformer()));
210201 }
211202 }
212203
213 return (ModuleId[]) ret.toArray(new ModuleId[ret.size()]);
204 return ret.toArray(new ModuleId[ret.size()]);
214205 }
215206
216207 /**
219210 * <p>
220211 * ModuleRevisionId are returned in the system namespace.
221212 * </p>
222 *
223 * @param criteria
224 * @param matcher
225 * @return
213 *
214 * @param moduleCrit ModuleRevisionId
215 * @param matcher PatternMatcher
216 * @return ModuleRevisionId[]
226217 */
227218 public ModuleRevisionId[] listModules(ModuleRevisionId moduleCrit, PatternMatcher matcher) {
228 List ret = new ArrayList();
229
230 Map criteria = new HashMap();
231 for (Iterator it = moduleCrit.getAttributes().entrySet().iterator(); it.hasNext();) {
232 Map.Entry entry = (Entry) it.next();
233 addMatcher(matcher, (String) entry.getValue(), criteria, (String) entry.getKey());
234 }
235
236 String[] tokensToList = (String[]) moduleCrit.getAttributes().keySet()
219 List<ModuleRevisionId> ret = new ArrayList<>();
220
221 Map<String, Object> criteria = new HashMap<>();
222 for (Map.Entry<String, String> entry : moduleCrit.getAttributes().entrySet()) {
223 addMatcher(matcher, entry.getValue(), criteria, entry.getKey());
224 }
225
226 String[] tokensToList = moduleCrit.getAttributes().keySet()
237227 .toArray(new String[moduleCrit.getAttributes().size()]);
238228
239 for (Iterator iter = settings.getResolvers().iterator(); iter.hasNext();) {
240 DependencyResolver resolver = (DependencyResolver) iter.next();
241 Map[] moduleIdAsMap = resolver.listTokenValues(tokensToList, criteria);
242 for (int i = 0; i < moduleIdAsMap.length; i++) {
243 String org = (String) moduleIdAsMap[i].get(IvyPatternHelper.ORGANISATION_KEY);
244 String name = (String) moduleIdAsMap[i].get(IvyPatternHelper.MODULE_KEY);
245 String branch = (String) moduleIdAsMap[i].get(IvyPatternHelper.BRANCH_KEY);
246 String rev = (String) moduleIdAsMap[i].get(IvyPatternHelper.REVISION_KEY);
247
248 Map foundExtraAtts = new HashMap();
249 Set qualAttributes = moduleCrit.getQualifiedExtraAttributes().keySet();
250 for (Iterator iter2 = qualAttributes.iterator(); iter2.hasNext();) {
251 String qualifiedKey = (String) iter2.next();
229 for (DependencyResolver resolver : settings.getResolvers()) {
230 Map<String, String>[] moduleIdAsMap = resolver.listTokenValues(tokensToList, criteria);
231 for (Map<String, String> moduleId : moduleIdAsMap) {
232 String org = moduleId.get(IvyPatternHelper.ORGANISATION_KEY);
233 String name = moduleId.get(IvyPatternHelper.MODULE_KEY);
234 String branch = moduleId.get(IvyPatternHelper.BRANCH_KEY);
235 String rev = moduleId.get(IvyPatternHelper.REVISION_KEY);
236
237 Map<String, String> foundExtraAtts = new HashMap<>();
238 for (String qualifiedKey : moduleCrit.getQualifiedExtraAttributes().keySet()) {
252239 String value = null;
253240 int colonIndex = qualifiedKey.indexOf(':');
254241 if (colonIndex == -1) {
255 value = (String) moduleIdAsMap[i].get(qualifiedKey);
242 value = moduleId.get(qualifiedKey);
256243 } else {
257 value = (String) moduleIdAsMap[i].get(qualifiedKey
258 .substring(colonIndex + 1));
244 value = moduleId.get(qualifiedKey.substring(colonIndex + 1));
259245 }
260246
261247 if (value != null) {
269255 }
270256 }
271257
272 return (ModuleRevisionId[]) ret.toArray(new ModuleRevisionId[ret.size()]);
258 return ret.toArray(new ModuleRevisionId[ret.size()]);
273259 }
274260
275261 /**
277263 * <p>
278264 * ModuleRevisionId are returned in the system namespace.
279265 * </p>
280 *
266 *
281267 * @param resolver
282268 * the resolver in which modules should looked up
283269 * @param moduleCrit
288274 */
289275 public ModuleRevisionId[] listModules(DependencyResolver resolver, ModuleRevisionId moduleCrit,
290276 PatternMatcher matcher) {
291 Map criteria = new HashMap();
292 for (Iterator it = moduleCrit.getAttributes().entrySet().iterator(); it.hasNext();) {
293 Map.Entry entry = (Entry) it.next();
294 addMatcher(matcher, (String) entry.getValue(), criteria, (String) entry.getKey());
295 }
296
297 String[] tokensToList = (String[]) moduleCrit.getAttributes().keySet()
277 Map<String, Object> criteria = new HashMap<>();
278 for (Map.Entry<String, String> entry : moduleCrit.getAttributes().entrySet()) {
279 addMatcher(matcher, entry.getValue(), criteria, entry.getKey());
280 }
281
282 String[] tokensToList = moduleCrit.getAttributes().keySet()
298283 .toArray(new String[moduleCrit.getAttributes().size()]);
299284
300 Map[] moduleIdAsMap = resolver.listTokenValues(tokensToList, criteria);
301 Set result = new LinkedHashSet(); // we use a Set to remove duplicates
302 for (int i = 0; i < moduleIdAsMap.length; i++) {
303 String org = (String) moduleIdAsMap[i].get(IvyPatternHelper.ORGANISATION_KEY);
304 String name = (String) moduleIdAsMap[i].get(IvyPatternHelper.MODULE_KEY);
305 String branch = (String) moduleIdAsMap[i].get(IvyPatternHelper.BRANCH_KEY);
306 String rev = (String) moduleIdAsMap[i].get(IvyPatternHelper.REVISION_KEY);
307
308 Map foundExtraAtts = new HashMap();
309 Set qualExtraAttributes = moduleCrit.getQualifiedExtraAttributes().keySet();
310 for (Iterator iter2 = qualExtraAttributes.iterator(); iter2.hasNext();) {
311 String qualifiedKey = (String) iter2.next();
285 Map<String, String>[] moduleIdAsMap = resolver.listTokenValues(tokensToList, criteria);
286 Set<ModuleRevisionId> result = new LinkedHashSet<>(); // we use a Set to remove duplicates
287 for (Map<String, String> moduleId : moduleIdAsMap) {
288 String org = moduleId.get(IvyPatternHelper.ORGANISATION_KEY);
289 String name = moduleId.get(IvyPatternHelper.MODULE_KEY);
290 String branch = moduleId.get(IvyPatternHelper.BRANCH_KEY);
291 String rev = moduleId.get(IvyPatternHelper.REVISION_KEY);
292
293 Map<String, String> foundExtraAtts = new HashMap<>();
294 for (String qualifiedKey : moduleCrit.getQualifiedExtraAttributes().keySet()) {
312295 String value = null;
313296 int colonIndex = qualifiedKey.indexOf(':');
314297 if (colonIndex == -1) {
315 value = (String) moduleIdAsMap[i].get(qualifiedKey);
298 value = moduleId.get(qualifiedKey);
316299 } else {
317 value = (String) moduleIdAsMap[i].get(qualifiedKey.substring(colonIndex + 1));
300 value = moduleId.get(qualifiedKey.substring(colonIndex + 1));
318301 }
319302
320303 if (value != null) {
327310 result.add(resolver.getNamespace().getToSystemTransformer().transform(modRevId));
328311 }
329312
330 return (ModuleRevisionId[]) result.toArray(new ModuleRevisionId[result.size()]);
331 }
332
333 private void addMatcher(PatternMatcher patternMatcher, String expression, Map criteria,
334 String key) {
313 return result.toArray(new ModuleRevisionId[result.size()]);
314 }
315
316 private void addMatcher(PatternMatcher patternMatcher, String expression,
317 Map<String, Object> criteria, String key) {
335318 if (expression == null) {
336319 return;
337320 }
344327 }
345328 }
346329
347 public Collection findModuleRevisionIds(DependencyResolver resolver, ModuleRevisionId pattern,
348 PatternMatcher matcher) {
349 Collection mrids = new ArrayList();
330 public Collection<ModuleRevisionId> findModuleRevisionIds(DependencyResolver resolver,
331 ModuleRevisionId pattern, PatternMatcher matcher) {
332 Collection<ModuleRevisionId> mrids = new ArrayList<>();
350333 String resolverName = resolver.getName();
351334
352335 Message.verbose("looking for modules matching " + pattern + " using " + matcher.getName());
353336 Namespace fromNamespace = null;
354337 if (resolver instanceof AbstractResolver) {
355 fromNamespace = ((AbstractResolver) resolver).getNamespace();
356 }
357
358 Collection modules = new ArrayList();
338 fromNamespace = resolver.getNamespace();
339 }
340
341 Collection<ModuleEntry> modules = new ArrayList<>();
359342
360343 OrganisationEntry[] orgs = resolver.listOrganisations();
361344 if (orgs == null || orgs.length == 0) {
369352 modules.addAll(Arrays.asList(resolver.listModules(new OrganisationEntry(resolver, org))));
370353 } else {
371354 Matcher orgMatcher = matcher.getMatcher(pattern.getOrganisation());
372 for (int i = 0; i < orgs.length; i++) {
373 String org = orgs[i].getOrganisation();
374 String systemOrg = org;
375 if (fromNamespace != null) {
376 systemOrg = NameSpaceHelper.transformOrganisation(org,
355 for (OrganisationEntry oe : orgs) {
356 String org = oe.getOrganisation();
357 String systemOrg = (fromNamespace == null) ? org
358 : NameSpaceHelper.transformOrganisation(org,
377359 fromNamespace.getToSystemTransformer());
378 }
379360 if (orgMatcher.matches(systemOrg)) {
380361 modules.addAll(Arrays.asList(resolver.listModules(new OrganisationEntry(
381362 resolver, org))));
385366 Message.debug("found " + modules.size() + " modules for " + pattern.getOrganisation()
386367 + " on " + resolverName);
387368 boolean foundModule = false;
388 for (Iterator iter = modules.iterator(); iter.hasNext();) {
389 ModuleEntry mEntry = (ModuleEntry) iter.next();
369 for (ModuleEntry mEntry : modules) {
390370
391371 ModuleId foundMid = new ModuleId(mEntry.getOrganisation(), mEntry.getModule());
392372 ModuleId systemMid = foundMid;
404384 + resolverName);
405385
406386 boolean foundRevision = false;
407 for (int j = 0; j < rEntries.length; j++) {
408 RevisionEntry rEntry = rEntries[j];
409
387 for (RevisionEntry rEntry : rEntries) {
410388 ModuleRevisionId foundMrid = ModuleRevisionId.newInstance(
411389 mEntry.getOrganisation(), mEntry.getModule(), rEntry.getRevision());
412390 ModuleRevisionId systemMrid = foundMrid;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1515 *
1616 */
1717 package org.apache.ivy.core.settings;
18
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.lang.reflect.Field;
25 import java.net.MalformedURLException;
26 import java.net.URL;
27 import java.net.URLClassLoader;
28 import java.security.AccessControlException;
29 import java.text.ParseException;
30 import java.util.ArrayList;
31 import java.util.Collection;
32 import java.util.HashMap;
33 import java.util.Iterator;
34 import java.util.LinkedHashMap;
35 import java.util.List;
36 import java.util.Map;
37 import java.util.Properties;
3818
3919 import org.apache.ivy.Ivy;
4020 import org.apache.ivy.core.IvyPatternHelper;
7555 import org.apache.ivy.plugins.latest.LatestRevisionStrategy;
7656 import org.apache.ivy.plugins.latest.LatestStrategy;
7757 import org.apache.ivy.plugins.latest.LatestTimeStrategy;
58 import org.apache.ivy.plugins.latest.WorkspaceLatestStrategy;
7859 import org.apache.ivy.plugins.lock.CreateFileLockStrategy;
7960 import org.apache.ivy.plugins.lock.LockStrategy;
8061 import org.apache.ivy.plugins.lock.NIOFileLockStrategy;
9172 import org.apache.ivy.plugins.report.LogReportOutputter;
9273 import org.apache.ivy.plugins.report.ReportOutputter;
9374 import org.apache.ivy.plugins.report.XmlReportOutputter;
75 import org.apache.ivy.plugins.resolver.AbstractWorkspaceResolver;
9476 import org.apache.ivy.plugins.resolver.ChainResolver;
9577 import org.apache.ivy.plugins.resolver.DependencyResolver;
9678 import org.apache.ivy.plugins.resolver.DualResolver;
9779 import org.apache.ivy.plugins.resolver.ResolverSettings;
80 import org.apache.ivy.plugins.resolver.WorkspaceChainResolver;
9881 import org.apache.ivy.plugins.signer.SignatureGenerator;
9982 import org.apache.ivy.plugins.trigger.Trigger;
10083 import org.apache.ivy.plugins.version.ChainVersionMatcher;
10689 import org.apache.ivy.util.Checks;
10790 import org.apache.ivy.util.FileUtil;
10891 import org.apache.ivy.util.Message;
92 import org.apache.ivy.util.StringUtils;
10993 import org.apache.ivy.util.filter.Filter;
11094 import org.apache.ivy.util.url.URLHandlerRegistry;
95
96 import java.io.File;
97 import java.io.FileInputStream;
98 import java.io.FileNotFoundException;
99 import java.io.IOException;
100 import java.io.InputStream;
101 import java.lang.reflect.Field;
102 import java.net.MalformedURLException;
103 import java.net.URL;
104 import java.net.URLClassLoader;
105 import java.security.AccessControlException;
106 import java.text.ParseException;
107 import java.util.ArrayList;
108 import java.util.Collection;
109 import java.util.HashMap;
110 import java.util.LinkedHashMap;
111 import java.util.List;
112 import java.util.Map;
113 import java.util.Properties;
114
115 import static org.apache.ivy.util.StringUtils.splitToArray;
111116
112117 public class IvySettings implements SortEngineSettings, PublishEngineSettings, ParserSettings,
113118 DeliverEngineSettings, CheckEngineSettings, InstallEngineSettings, ResolverSettings,
114119 ResolveEngineSettings, RetrieveEngineSettings, RepositoryManagementEngineSettings {
115 private static final long INTERUPT_TIMEOUT = 2000;
116
117 private Map typeDefs = new HashMap();
118
119 private Map resolversMap = new HashMap();
120 private static final long INTERRUPT_TIMEOUT = 2000;
121
122 private Map<String, Class<?>> typeDefs = new HashMap<>();
123
124 private Map<String, DependencyResolver> resolversMap = new HashMap<>();
120125
121126 private DependencyResolver defaultResolver;
122127
130135
131136 private boolean checkUpToDate = true;
132137
133 private ModuleRules moduleSettings = new ModuleRules();
134
135 // Map (String conflictManagerName -> ConflictManager)
136 private Map conflictsManager = new HashMap();
137
138 // Map (String latestStrategyName -> LatestStrategy)
139 private Map latestStrategies = new HashMap();
140
141 // Map (String name -> LockStrategy)
142 private Map lockStrategies = new HashMap();
143
144 // Map (String namespaceName -> Namespace)
145 private Map namespaces = new HashMap();
146
147 // Map (String matcherName -> Matcher)
148 private Map matchers = new HashMap();
149
150 // Map (String outputterName -> ReportOutputter)
151 private Map reportOutputters = new HashMap();
152
153 // Map (String matcherName -> VersionMatcher)
154 private Map versionMatchers = new HashMap();
155
156 // Map (String name -> CircularDependencyStrategy)
157 private Map circularDependencyStrategies = new HashMap();
158
159 // Map (String name -> RepositoryCacheManager)
160 private Map repositoryCacheManagers = new HashMap();
161
162 // Map (String name -> SignatureGenerator)
163 private Map signatureGenerators = new HashMap();
164
165 // List (Trigger)
166 private List triggers = new ArrayList();
138 private ModuleRules<ModuleSettings> moduleSettings = new ModuleRules<>();
139
140 private Map<String, ConflictManager> conflictsManager = new HashMap<>();
141
142 private Map<String, LatestStrategy> latestStrategies = new HashMap<>();
143
144 private Map<String, LockStrategy> lockStrategies = new HashMap<>();
145
146 private Map<String, Namespace> namespaces = new HashMap<>();
147
148 private Map<String, PatternMatcher> matchers = new HashMap<>();
149
150 private Map<String, ReportOutputter> reportOutputters = new HashMap<>();
151
152 private Map<String, VersionMatcher> versionMatchers = new HashMap<>();
153
154 private Map<String, CircularDependencyStrategy> circularDependencyStrategies = new HashMap<>();
155
156 private Map<String, RepositoryCacheManager> repositoryCacheManagers = new HashMap<>();
157
158 private Map<String, SignatureGenerator> signatureGenerators = new HashMap<>();
159
160 private List<Trigger> triggers = new ArrayList<>();
167161
168162 private IvyVariableContainer variableContainer = new IvyVariableContainerImpl();
169163
181175
182176 private ResolutionCacheManager resolutionCacheManager = null;
183177
184 private List listingIgnore = new ArrayList();
178 private List<String> listingIgnore = new ArrayList<>();
185179
186180 private boolean repositoriesConfigured;
187181
191185
192186 private File baseDir = new File(".").getAbsoluteFile();
193187
194 private List classpathURLs = new ArrayList();
188 private List<URL> classpathURLs = new ArrayList<>();
195189
196190 private ClassLoader classloader;
197191
216210 private String defaultResolveMode = ResolveOptions.RESOLVEMODE_DEFAULT;
217211
218212 private PackingRegistry packingRegistry = new PackingRegistry();
213
214 private AbstractWorkspaceResolver workspaceResolver;
215
216 private final Map<String, TimeoutConstraint> timeoutConstraints = new HashMap<>();
219217
220218 public IvySettings() {
221219 this(new IvyVariableContainerImpl());
229227
230228 String ivyTypeDefs = System.getProperty("ivy.typedef.files");
231229 if (ivyTypeDefs != null) {
232 String[] files = ivyTypeDefs.split("\\,");
233 for (int i = 0; i < files.length; i++) {
230 for (String file : splitToArray(ivyTypeDefs)) {
234231 try {
235 typeDefs(
236 new FileInputStream(Checks.checkAbsolute(files[i].trim(),
232 typeDefs(new FileInputStream(Checks.checkAbsolute(file,
237233 "ivy.typedef.files")), true);
238234 } catch (FileNotFoundException e) {
239 Message.warn("typedefs file not found: " + files[i].trim());
235 Message.warn("typedefs file not found: " + file);
240236 } catch (IOException e) {
241 Message.warn("problem with typedef file: " + files[i].trim(), e);
237 Message.warn("problem with typedef file: " + file, e);
242238 }
243239 }
244240 } else {
277273
278274 try {
279275 // GlobPatternMatcher is optional. Only add it when available.
280 Class globClazz = IvySettings.class.getClassLoader().loadClass(
281 "org.apache.ivy.plugins.matcher.GlobPatternMatcher");
276 @SuppressWarnings("unchecked")
277 Class<? extends PatternMatcher> globClazz = (Class<? extends PatternMatcher>) IvySettings.class
278 .getClassLoader()
279 .loadClass("org.apache.ivy.plugins.matcher.GlobPatternMatcher");
282280 Field instanceField = globClazz.getField("INSTANCE");
283281 addMatcher((PatternMatcher) instanceField.get(null));
284282 } catch (Exception e) {
304302
305303 private synchronized void addSystemProperties() {
306304 try {
307 addAllVariables((Map) System.getProperties().clone());
305 addAllVariables((Map<?, ?>) System.getProperties().clone());
308306 } catch (AccessControlException ex) {
309307 Message.verbose("access denied to getting all system properties: they won't be available as Ivy variables."
310308 + "\nset " + ex.getPermission() + " permission if you want to access them");
314312 /**
315313 * Call this method to ask ivy to configure some variables using either a remote or a local
316314 * properties file
315 *
316 * @param remote boolean
317317 */
318 @SuppressWarnings("deprecation")
318319 public synchronized void configureRepositories(boolean remote) {
319320 if (!repositoriesConfigured) {
320321 Properties props = new Properties();
321322 boolean configured = false;
322323 if (useRemoteConfig && remote) {
323324 try {
324 URL url = new URL("http://ant.apache.org/ivy/repository.properties");
325 URL url = new URL("https://ant.apache.org/ivy/repository.properties");
325326 Message.verbose("configuring repositories with " + url);
326327 props.load(URLHandlerRegistry.getDefault().openStream(url));
327328 configured = true;
370371 }
371372
372373 public synchronized void typeDefs(Properties p, boolean silentFail) {
373 for (Iterator iter = p.keySet().iterator(); iter.hasNext();) {
374 String name = (String) iter.next();
375 typeDef(name, p.getProperty(name), silentFail);
374 for (Map.Entry<Object, Object> entry : p.entrySet()) {
375 typeDef(entry.getKey().toString(), entry.getValue().toString(), silentFail);
376376 }
377377 }
378378
391391 try {
392392 new XmlSettingsParser(this).parse(settingsFile.toURI().toURL());
393393 } catch (MalformedURLException e) {
394 IllegalArgumentException iae = new IllegalArgumentException(
395 "given file cannot be transformed to url: " + settingsFile);
396 iae.initCause(e);
397 throw iae;
394 throw new IllegalArgumentException(
395 "given file cannot be transformed to url: " + settingsFile, e);
398396 }
399397 setVariable("ivy.default.ivy.user.dir", getDefaultIvyUserDir().getAbsolutePath(), false);
400398 Message.verbose("settings loaded (" + (System.currentTimeMillis() - start) + "ms)");
423421 * Default initialization of settings, useful when you don't want to load your settings from a
424422 * settings file or URL, but prefer to set them manually. By calling this method you will still
425423 * have the basic initialization done when loading settings.
426 *
427 * @throws IOException
424 *
425 * @throws IOException if something goes wrong
428426 */
429427 public synchronized void defaultInit() throws IOException {
430428 if (getVariable("ivy.default.ivy.user.dir") != null) {
485483 setVariable("ivy.settings.dir.url", new File(settingsFile.getAbsolutePath())
486484 .getParentFile().toURI().toURL().toExternalForm());
487485 } catch (MalformedURLException e) {
488 IllegalArgumentException iae = new IllegalArgumentException(
489 "given file cannot be transformed to url: " + settingsFile);
490 iae.initCause(e);
491 throw iae;
486 throw new IllegalArgumentException(
487 "given file cannot be transformed to url: " + settingsFile, e);
492488 }
493489 }
494490
495491 /**
496492 * Sets a deprecated variable with the value of the new variable
497 *
493 *
498494 * @param deprecatedKey
499495 * the deprecated variable name
500496 * @param newKey
531527
532528 if (!classpathURLs.isEmpty()) {
533529 Message.verbose("\t-- " + classpathURLs.size() + " custom classpath urls:");
534 for (Iterator iter = classpathURLs.iterator(); iter.hasNext();) {
535 Message.debug("\t\t" + iter.next());
530 for (URL url : classpathURLs) {
531 Message.debug("\t\t" + url);
536532 }
537533 }
538534 Message.verbose("\t-- " + resolversMap.size() + " resolvers:");
539 for (Iterator iter = resolversMap.values().iterator(); iter.hasNext();) {
540 DependencyResolver resolver = (DependencyResolver) iter.next();
535 for (DependencyResolver resolver : resolversMap.values()) {
541536 resolver.dumpSettings();
542537 }
543538 Message.debug("\tmodule settings:");
599594 variableContainer.setVariable(varName, value, overwrite);
600595 }
601596
602 public synchronized void addAllVariables(Map variables) {
597 public synchronized void addAllVariables(Map<?, ?> variables) {
603598 addAllVariables(variables, true);
604599 }
605600
606601 public synchronized void addAllVariables(Map<?, ?> variables, boolean overwrite) {
607602 for (Map.Entry<?, ?> entry : variables.entrySet()) {
608 String key = entry.getKey().toString();
609603 Object val = entry.getValue();
610604 if (val == null || val instanceof String) {
611 setVariable(key, (String) val, overwrite);
605 setVariable(entry.getKey().toString(), (String) val, overwrite);
612606 }
613607 }
614608 }
615609
616610 /**
617611 * Substitute variables in the given string by their value found in the current set of variables
618 *
612 *
619613 * @param str
620614 * the string in which substitution should be made
621615 * @return the string where all current ivy variables have been substituted by their value If
628622 /**
629623 * Substitute variables in the given map values by their value found in the current set of
630624 * variables
631 *
625 *
632626 * @param strings
633627 * the map of strings in which substitution should be made
634628 * @return a new map of strings in which all current ivy variables in values have been
635629 * substituted by their value
636630 */
637 public synchronized Map/* <String, String> */substitute(Map/* <String, String> */strings) {
638 Map substituted = new LinkedHashMap();
639 for (Iterator it = strings.entrySet().iterator(); it.hasNext();) {
640 Map.Entry entry = (Map.Entry) it.next();
641 substituted.put(entry.getKey(), substitute((String) entry.getValue()));
631 public synchronized Map<String, String> substitute(Map<String, String> strings) {
632 Map<String, String> substituted = new LinkedHashMap<>();
633 for (Map.Entry<String, String> entry : strings.entrySet()) {
634 substituted.put(entry.getKey(), substitute(entry.getValue()));
642635 }
643636 return substituted;
644637 }
646639 /**
647640 * Returns the variables loaded in configuration file. Those variables may better be seen as ant
648641 * properties
649 *
650 * @return
642 *
643 * @return IvyVariableContainer
651644 */
652645 public synchronized IvyVariableContainer getVariables() {
653646 return variableContainer;
654647 }
655648
656 public synchronized Class typeDef(String name, String className) {
649 public synchronized Class<?> typeDef(String name, String className) {
657650 return typeDef(name, className, false);
658651 }
659652
660 public synchronized Class typeDef(String name, String className, boolean silentFail) {
661 Class clazz = classForName(className, silentFail);
653 public synchronized Class<?> typeDef(String name, String className, boolean silentFail) {
654 Class<?> clazz = classForName(className, silentFail);
662655 if (clazz != null) {
663656 typeDefs.put(name, clazz);
664657 }
665658 return clazz;
666659 }
667660
668 private Class classForName(String className, boolean silentFail) {
661 private Class<?> classForName(String className, boolean silentFail) {
669662 try {
670663 return getClassLoader().loadClass(className);
671664 } catch (ClassNotFoundException e) {
686679 classloader = Ivy.class.getClassLoader();
687680 } else {
688681 classloader = new URLClassLoader(
689 (URL[]) classpathURLs.toArray(new URL[classpathURLs.size()]),
682 classpathURLs.toArray(new URL[classpathURLs.size()]),
690683 Ivy.class.getClassLoader());
691684 }
692685 }
698691 classloader = null;
699692 }
700693
701 public synchronized Map getTypeDefs() {
694 public synchronized Map<String, Class<?>> getTypeDefs() {
702695 return typeDefs;
703696 }
704697
705 public synchronized Class getTypeDef(String name) {
706 return (Class) typeDefs.get(name);
698 public synchronized Class<?> getTypeDef(String name) {
699 return typeDefs.get(name);
707700 }
708701
709702 // methods which match ivy conf method signature specs
725718 }
726719
727720 public synchronized SignatureGenerator getSignatureGenerator(String name) {
728 return (SignatureGenerator) signatureGenerators.get(name);
721 return signatureGenerators.get(name);
729722 }
730723
731724 public synchronized void addResolver(DependencyResolver resolver) {
735728 init(resolver);
736729 resolversMap.put(resolver.getName(), resolver);
737730 if (resolver instanceof ChainResolver) {
738 List subresolvers = ((ChainResolver) resolver).getResolvers();
739 for (Iterator iter = subresolvers.iterator(); iter.hasNext();) {
740 DependencyResolver dr = (DependencyResolver) iter.next();
731 List<DependencyResolver> subresolvers = ((ChainResolver) resolver).getResolvers();
732 for (DependencyResolver dr : subresolvers) {
741733 addResolver(dr);
742734 }
743735 } else if (resolver instanceof DualResolver) {
781773
782774 /**
783775 * regular expressions as explained in Pattern class may be used in attributes
776 *
777 * @param attributes Map
778 * @param matcher PatternMatcher
779 * @param resolverName String
780 * @param branch String
781 * @param conflictManager String
782 * @param resolveMode String
784783 */
785 public synchronized void addModuleConfiguration(Map attributes, PatternMatcher matcher,
786 String resolverName, String branch, String conflictManager, String resolveMode) {
784 public synchronized void addModuleConfiguration(Map<String, String> attributes,
785 PatternMatcher matcher, String resolverName, String branch, String conflictManager,
786 String resolveMode) {
787787 checkResolverName(resolverName);
788788 moduleSettings.defineRule(new MapMatcher(attributes, matcher), new ModuleSettings(
789789 resolverName, branch, conflictManager, resolveMode));
794794 * <p>
795795 * If the specified file name is relative it is resolved with respect to the settings's base
796796 * directory.
797 *
797 *
798798 * @param fileName
799799 * The name of the file to resolve. Must not be <code>null</code>.
800 *
800 *
801801 * @return the resolved File.
802 *
802 *
803803 */
804804 public synchronized File resolveFile(String fileName) {
805805 return FileUtil.resolveFile(baseDir, fileName);
889889 dictatorResolver = resolver;
890890 }
891891
892 private DependencyResolver getDictatorResolver() {
893 if (dictatorResolver == null) {
894 return null;
895 }
896 if (workspaceResolver != null && !(dictatorResolver instanceof WorkspaceChainResolver)) {
897 dictatorResolver = new WorkspaceChainResolver(this, dictatorResolver, workspaceResolver);
898 }
899 return dictatorResolver;
900 }
901
892902 public synchronized DependencyResolver getResolver(ModuleRevisionId mrid) {
893 if (dictatorResolver != null) {
894 return dictatorResolver;
903 DependencyResolver r = getDictatorResolver();
904 if (r != null) {
905 return r;
895906 }
896907 String resolverName = getResolverName(mrid);
897908 return getResolver(resolverName);
902913 }
903914
904915 public synchronized DependencyResolver getResolver(String resolverName) {
905 if (dictatorResolver != null) {
906 return dictatorResolver;
907 }
908 DependencyResolver resolver = (DependencyResolver) resolversMap.get(resolverName);
916 DependencyResolver r = getDictatorResolver();
917 if (r != null) {
918 return r;
919 }
920 DependencyResolver resolver = resolversMap.get(resolverName);
909921 if (resolver == null) {
910922 Message.error("unknown resolver " + resolverName);
923 } else if (workspaceResolver != null && !(resolver instanceof WorkspaceChainResolver)) {
924 resolver = new WorkspaceChainResolver(this, resolver, workspaceResolver);
925 resolversMap.put(resolver.getName(), resolver);
926 resolversMap.put(resolverName, resolver);
911927 }
912928 return resolver;
913929 }
914930
915931 public synchronized DependencyResolver getDefaultResolver() {
916 if (dictatorResolver != null) {
917 return dictatorResolver;
932 DependencyResolver r = getDictatorResolver();
933 if (r != null) {
934 return r;
918935 }
919936 if (defaultResolver == null) {
920 defaultResolver = (DependencyResolver) resolversMap.get(defaultResolverName);
937 defaultResolver = resolversMap.get(defaultResolverName);
938 }
939 if (workspaceResolver != null && !(defaultResolver instanceof WorkspaceChainResolver)) {
940 defaultResolver = new WorkspaceChainResolver(this, defaultResolver, workspaceResolver);
921941 }
922942 return defaultResolver;
923943 }
924944
925945 public synchronized String getResolverName(ModuleRevisionId mrid) {
926 ModuleSettings ms = (ModuleSettings) moduleSettings.getRule(mrid, new Filter() {
927 public boolean accept(Object o) {
928 return ((ModuleSettings) o).getResolverName() != null;
946 ModuleSettings ms = moduleSettings.getRule(mrid, new Filter<ModuleSettings>() {
947 public boolean accept(ModuleSettings o) {
948 return o.getResolverName() != null;
929949 }
930950 });
931951 return ms == null ? defaultResolverName : ms.getResolverName();
932952 }
933953
934954 public synchronized String getDefaultBranch(ModuleId moduleId) {
935 ModuleSettings ms = (ModuleSettings) moduleSettings.getRule(moduleId, new Filter() {
936 public boolean accept(Object o) {
937 return ((ModuleSettings) o).getBranch() != null;
955 ModuleSettings ms = moduleSettings.getRule(moduleId, new Filter<ModuleSettings>() {
956 public boolean accept(ModuleSettings o) {
957 return o.getBranch() != null;
938958 }
939959 });
940960 return ms == null ? getDefaultBranch() : ms.getBranch();
949969 }
950970
951971 public synchronized ConflictManager getConflictManager(ModuleId moduleId) {
952 ModuleSettings ms = (ModuleSettings) moduleSettings.getRule(moduleId, new Filter() {
953 public boolean accept(Object o) {
954 return ((ModuleSettings) o).getConflictManager() != null;
972 ModuleSettings ms = moduleSettings.getRule(moduleId, new Filter<ModuleSettings>() {
973 public boolean accept(ModuleSettings o) {
974 return o.getConflictManager() != null;
955975 }
956976 });
957977 if (ms == null) {
967987 }
968988
969989 public synchronized String getResolveMode(ModuleId moduleId) {
970 ModuleSettings ms = (ModuleSettings) moduleSettings.getRule(moduleId, new Filter() {
971 public boolean accept(Object o) {
972 return ((ModuleSettings) o).getResolveMode() != null;
990 ModuleSettings ms = moduleSettings.getRule(moduleId, new Filter<ModuleSettings>() {
991 public boolean accept(ModuleSettings o) {
992 return o.getResolveMode() != null;
973993 }
974994 });
975995 return ms == null ? getDefaultResolveMode() : ms.getResolveMode();
9911011 if ("default".equals(name)) {
9921012 return getDefaultConflictManager();
9931013 }
994 return (ConflictManager) conflictsManager.get(name);
1014 return conflictsManager.get(name);
9951015 }
9961016
9971017 public synchronized void addConflictManager(String name, ConflictManager cm) {
10071027 if ("default".equals(name)) {
10081028 return getDefaultLatestStrategy();
10091029 }
1010 return (LatestStrategy) latestStrategies.get(name);
1030 LatestStrategy strategy = latestStrategies.get(name);
1031 if (workspaceResolver != null && !(strategy instanceof WorkspaceLatestStrategy)) {
1032 strategy = new WorkspaceLatestStrategy(strategy);
1033 latestStrategies.put(name, strategy);
1034 }
1035 return strategy;
10111036 }
10121037
10131038 public synchronized void addLatestStrategy(String name, LatestStrategy latest) {
10231048 if ("default".equals(name)) {
10241049 return getDefaultLockStrategy();
10251050 }
1026 return (LockStrategy) lockStrategies.get(name);
1051 return lockStrategies.get(name);
10271052 }
10281053
10291054 public synchronized void addLockStrategy(String name, LockStrategy lockStrategy) {
10391064 if ("system".equals(name)) {
10401065 return getSystemNamespace();
10411066 }
1042 return (Namespace) namespaces.get(name);
1067 return namespaces.get(name);
10431068 }
10441069
10451070 public final Namespace getSystemNamespace() {
10511076 namespaces.put(ns.getName(), ns);
10521077 }
10531078
1079 public void addConfigured(final NamedTimeoutConstraint timeoutConstraint) {
1080 if (timeoutConstraint == null) {
1081 return;
1082 }
1083 final String name = timeoutConstraint.getName();
1084 StringUtils.assertNotNullNorEmpty(name, "Name of a timeout constraint cannot be null or empty string");
1085 this.timeoutConstraints.put(name, timeoutConstraint);
1086 }
1087
1088 @Override
1089 public TimeoutConstraint getTimeoutConstraint(final String name) {
1090 return this.timeoutConstraints.get(name);
1091 }
1092
10541093 public synchronized void addConfigured(PatternMatcher m) {
10551094 addMatcher(m);
10561095 }
10571096
10581097 public synchronized PatternMatcher getMatcher(String name) {
1059 return (PatternMatcher) matchers.get(name);
1098 return matchers.get(name);
10601099 }
10611100
10621101 public synchronized void addMatcher(PatternMatcher m) {
10691108 }
10701109
10711110 public synchronized RepositoryCacheManager getRepositoryCacheManager(String name) {
1072 return (RepositoryCacheManager) repositoryCacheManagers.get(name);
1111 return repositoryCacheManagers.get(name);
10731112 }
10741113
10751114 public synchronized void addRepositoryCacheManager(RepositoryCacheManager c) {
10781117 }
10791118
10801119 public synchronized RepositoryCacheManager[] getRepositoryCacheManagers() {
1081 return (RepositoryCacheManager[]) repositoryCacheManagers.values().toArray(
1120 return repositoryCacheManagers.values().toArray(
10821121 new RepositoryCacheManager[repositoryCacheManagers.size()]);
10831122 }
10841123
10871126 }
10881127
10891128 public synchronized ReportOutputter getReportOutputter(String name) {
1090 return (ReportOutputter) reportOutputters.get(name);
1129 return reportOutputters.get(name);
10911130 }
10921131
10931132 public synchronized void addReportOutputter(ReportOutputter outputter) {
10961135 }
10971136
10981137 public synchronized ReportOutputter[] getReportOutputters() {
1099 return (ReportOutputter[]) reportOutputters.values().toArray(
1100 new ReportOutputter[reportOutputters.size()]);
1138 return reportOutputters.values().toArray(new ReportOutputter[reportOutputters.size()]);
11011139 }
11021140
11031141 public synchronized void addConfigured(VersionMatcher vmatcher) {
11051143 }
11061144
11071145 public synchronized VersionMatcher getVersionMatcher(String name) {
1108 return (VersionMatcher) versionMatchers.get(name);
1146 return versionMatchers.get(name);
11091147 }
11101148
11111149 public synchronized void addVersionMatcher(VersionMatcher vmatcher) {
11231161 }
11241162
11251163 public synchronized VersionMatcher[] getVersionMatchers() {
1126 return (VersionMatcher[]) versionMatchers.values().toArray(
1127 new VersionMatcher[versionMatchers.size()]);
1164 return versionMatchers.values().toArray(new VersionMatcher[versionMatchers.size()]);
11281165 }
11291166
11301167 public synchronized VersionMatcher getVersionMatcher() {
11511188 if ("default".equals(name)) {
11521189 name = "warn";
11531190 }
1154 return (CircularDependencyStrategy) circularDependencyStrategies.get(name);
1191 return circularDependencyStrategies.get(name);
11551192 }
11561193
11571194 public synchronized void setCircularDependencyStrategy(CircularDependencyStrategy strategy) {
11851222
11861223 /**
11871224 * Returns the file names of the files that should be ignored when creating a file listing.
1225 *
1226 * @return String[]
11881227 */
11891228 public synchronized String[] getIgnorableFilenames() {
1190 return (String[]) listingIgnore.toArray(new String[listingIgnore.size()]);
1229 return listingIgnore.toArray(new String[listingIgnore.size()]);
11911230 }
11921231
11931232 /**
11941233 * Filters the names list by removing all names that should be ignored as defined by the listing
11951234 * ignore list
1196 *
1197 * @param names
1235 *
1236 * @param names ditto
11981237 */
1199 public synchronized void filterIgnore(Collection names) {
1238 public synchronized void filterIgnore(Collection<String> names) {
12001239 names.removeAll(listingIgnore);
12011240 }
12021241
12181257
12191258 public synchronized String getVariable(String name) {
12201259 return variableContainer.getVariable(name);
1260 }
1261
1262 /**
1263 * Returns a variable as boolean value.
1264 * @param name name of the variable
1265 * @param valueIfUnset value if the variable is unset
1266 * @return <tt>true</tt> if the variable is <tt>'true'</tt> (ignoring case)
1267 * or the value of <i>valueIfUnset</i> if the variable is <tt>null</tt>
1268 */
1269 public synchronized boolean getVariableAsBoolean(String name, boolean valueIfUnset) {
1270 String var = getVariable(name);
1271 return var == null ? valueIfUnset : Boolean.valueOf(var);
12211272 }
12221273
12231274 public synchronized ConflictManager getDefaultConflictManager() {
12351286 public synchronized LatestStrategy getDefaultLatestStrategy() {
12361287 if (defaultLatestStrategy == null) {
12371288 defaultLatestStrategy = new LatestRevisionStrategy();
1289 }
1290 if (workspaceResolver != null
1291 && !(defaultLatestStrategy instanceof WorkspaceLatestStrategy)) {
1292 defaultLatestStrategy = new WorkspaceLatestStrategy(defaultLatestStrategy);
12381293 }
12391294 return defaultLatestStrategy;
12401295 }
12851340 triggers.add(trigger);
12861341 }
12871342
1288 public synchronized List getTriggers() {
1343 public synchronized List<Trigger> getTriggers() {
12891344 return triggers;
12901345 }
12911346
13021357 }
13031358
13041359 public synchronized boolean logModulesInUse() {
1305 String var = getVariable("ivy.log.modules.in.use");
1306 return var == null || Boolean.valueOf(var).booleanValue();
1360 return getVariableAsBoolean("ivy.log.modules.in.use", true);
13071361 }
13081362
13091363 public synchronized boolean logModuleWhenFound() {
1310 String var = getVariable("ivy.log.module.when.found");
1311 return var == null || Boolean.valueOf(var).booleanValue();
1364 return getVariableAsBoolean("ivy.log.module.when.found", true);
13121365 }
13131366
13141367 public synchronized boolean logResolvedRevision() {
1315 String var = getVariable("ivy.log.resolved.revision");
1316 return var == null || Boolean.valueOf(var).booleanValue();
1368 return getVariableAsBoolean("ivy.log.resolved.revision", true);
13171369 }
13181370
13191371 public synchronized boolean debugConflictResolution() {
13201372 if (debugConflictResolution == null) {
1321 String var = getVariable("ivy.log.conflict.resolution");
1322 debugConflictResolution = Boolean.valueOf(var != null
1323 && Boolean.valueOf(var).booleanValue());
1324 }
1325 return debugConflictResolution.booleanValue();
1373 debugConflictResolution = getVariableAsBoolean("ivy.log.conflict.resolution", false);
1374 }
1375 return debugConflictResolution;
13261376 }
13271377
13281378 public synchronized boolean debugLocking() {
13291379 if (debugLocking == null) {
1330 String var = getVariable("ivy.log.locking");
1331 debugLocking = Boolean.valueOf(var != null && Boolean.valueOf(var).booleanValue());
1332 }
1333 return debugLocking.booleanValue();
1380 debugLocking = getVariableAsBoolean("ivy.log.locking", false);
1381 }
1382 return debugLocking;
13341383 }
13351384
13361385 public synchronized boolean dumpMemoryUsage() {
13371386 if (dumpMemoryUsage == null) {
1338 String var = getVariable("ivy.log.memory");
1339 dumpMemoryUsage = Boolean.valueOf(var != null && Boolean.valueOf(var).booleanValue());
1340 }
1341 return dumpMemoryUsage.booleanValue();
1387 dumpMemoryUsage = getVariableAsBoolean("ivy.log.memory", false);
1388 }
1389 return dumpMemoryUsage;
13421390 }
13431391
13441392 public synchronized boolean logNotConvertedExclusionRule() {
13741422 this.resolveMode = resolveMode;
13751423 }
13761424
1425 @Override
13771426 public String toString() {
13781427 return (resolverName != null ? "resolver: " + resolverName : "")
13791428 + (branch != null ? "branch: " + branch : "")
13991448 }
14001449
14011450 public final long getInterruptTimeout() {
1402 return INTERUPT_TIMEOUT;
1403 }
1404
1405 public synchronized Collection getResolvers() {
1451 return INTERRUPT_TIMEOUT;
1452 }
1453
1454 public synchronized Collection<DependencyResolver> getResolvers() {
14061455 return resolversMap.values();
14071456 }
14081457
1409 public synchronized Collection getResolverNames() {
1458 public synchronized Collection<String> getResolverNames() {
14101459 return resolversMap.keySet();
14111460 }
14121461
1413 public synchronized Collection getMatcherNames() {
1462 public synchronized Collection<String> getMatcherNames() {
14141463 return matchers.keySet();
14151464 }
14161465
14201469
14211470 /**
14221471 * Use a different variable container.
1423 *
1424 * @param variables
1472 *
1473 * @param variables IvyVariableContainer
14251474 */
14261475 public synchronized void setVariableContainer(IvyVariableContainer variables) {
14271476 variableContainer = variables;
14671516 /**
14681517 * Validates the settings, throwing an {@link IllegalStateException} if the current state is not
14691518 * valid.
1470 *
1519 *
14711520 * @throws IllegalStateException
14721521 * if the settings is not valid.
14731522 */
14851534
14861535 /**
14871536 * Validates all {@link Validatable} objects in the collection.
1488 *
1489 * @param objects
1537 *
1538 * @param values
14901539 * the collection of objects to validate.
14911540 * @throws IllegalStateException
14921541 * if any of the objects is not valid.
14931542 */
1494 private void validateAll(Collection values) {
1495 for (Iterator iterator = values.iterator(); iterator.hasNext();) {
1496 Object object = iterator.next();
1543 private void validateAll(Collection<?> values) {
1544 for (Object object : values) {
14971545 if (object instanceof Validatable) {
14981546 ((Validatable) object).validate();
14991547 }
15121560 public PackingRegistry getPackingRegistry() {
15131561 return packingRegistry;
15141562 }
1563
1564 public void addConfigured(AbstractWorkspaceResolver workspaceResolver) {
1565 this.workspaceResolver = workspaceResolver;
1566 if (workspaceResolver != null) {
1567 workspaceResolver.setSettings(this);
1568 DefaultRepositoryCacheManager cacheManager = new DefaultRepositoryCacheManager();
1569 String cacheName = "workspace-resolver-cache-" + workspaceResolver.getName();
1570 cacheManager.setBasedir(new File(getDefaultCache(), cacheName));
1571 cacheManager.setCheckmodified(true);
1572 cacheManager.setUseOrigin(true);
1573 cacheManager.setName(cacheName);
1574 addRepositoryCacheManager(cacheManager);
1575 workspaceResolver.setCache(cacheName);
1576 }
1577
1578 }
15151579 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 */
2222 public interface IvyVariableContainer extends Cloneable {
2323
24 public void setVariable(String varName, String value, boolean overwrite);
24 void setVariable(String varName, String value, boolean overwrite);
2525
26 public String getVariable(String name);
26 String getVariable(String name);
2727
2828 /**
2929 * Specifies the prefix used to indicate a variable is an environment variable. If the prefix
3030 * doesn't end with a '.', it will be added automatically.
31 *
31 *
3232 * @param prefix
3333 * the prefix to use for the environment variables
3434 */
35 public void setEnvironmentPrefix(String prefix);
35 void setEnvironmentPrefix(String prefix);
3636
37 public Object clone();
37 Object clone();
3838 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424
2525 public class IvyVariableContainerImpl implements IvyVariableContainer {
2626
27 private Map variables;
27 private Map<String, String> variables;
2828
2929 private String envPrefix;
3030
3131 public IvyVariableContainerImpl() {
32 this.variables = new HashMap();
32 this.variables = new HashMap<>();
3333 }
3434
35 public IvyVariableContainerImpl(Map variables) {
35 public IvyVariableContainerImpl(Map<String, String> variables) {
3636 this.variables = variables;
3737 }
3838
3939 /*
4040 * (non-Javadoc)
41 *
41 *
4242 * @see org.apache.ivy.core.settings.IvyVariableContainer#setVariable(java.lang.String,
4343 * java.lang.String, boolean)
4444 */
5252 }
5353
5454 public void setEnvironmentPrefix(String prefix) {
55 if ((prefix != null) && !prefix.endsWith(".")) {
55 if (prefix != null && !prefix.endsWith(".")) {
5656 this.envPrefix = prefix + ".";
5757 } else {
5858 this.envPrefix = prefix;
6363 return IvyPatternHelper.substituteVariables(value, this);
6464 }
6565
66 protected Map getVariables() {
66 protected Map<String, String> getVariables() {
6767 return variables;
6868 }
6969
7373
7474 /*
7575 * (non-Javadoc)
76 *
76 *
7777 * @see org.apache.ivy.core.settings.IvyVariableContainer#getVariable(java.lang.String)
7878 */
7979 public String getVariable(String name) {
8080 String val = null;
81 if ((envPrefix != null) && name.startsWith(envPrefix)) {
81 if (envPrefix != null && name.startsWith(envPrefix)) {
8282 val = System.getenv(name.substring(envPrefix.length()));
8383 } else {
84 val = (String) variables.get(name);
84 val = variables.get(name);
8585 }
8686
8787 return val;
9494 } catch (CloneNotSupportedException e) {
9595 throw new RuntimeException("unable to clone a " + this.getClass());
9696 }
97 clone.variables = new HashMap(this.variables);
97 clone.variables = new HashMap<>(this.variables);
9898 return clone;
9999 }
100100 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 package org.apache.ivy.core.settings;
19
20 import org.apache.ivy.util.StringUtils;
21
22 /**
23 * An implementation of {@link TimeoutConstraint} which can be identified by a name
24 */
25 public class NamedTimeoutConstraint implements TimeoutConstraint {
26
27 private String name;
28
29 private int connectionTimeout = -1;
30
31 private int readTimeout = -1;
32
33 public NamedTimeoutConstraint() {
34 }
35
36 public NamedTimeoutConstraint(final String name) {
37 StringUtils.assertNotNullNorEmpty(name, "Name of a timeout constraint cannot be null or empty string");
38 this.name = name;
39 }
40
41 public void setName(final String name) {
42 StringUtils.assertNotNullNorEmpty(name, "Name of a timeout constraint cannot be null or empty string");
43 this.name = name;
44 }
45
46 /**
47 * @return Returns the name of the timeout constraint
48 */
49 public String getName() {
50 return this.name;
51 }
52
53 @Override
54 public int getConnectionTimeout() {
55 return this.connectionTimeout;
56 }
57
58 @Override
59 public int getReadTimeout() {
60 return this.readTimeout;
61 }
62
63 /**
64 * Sets the connection timeout of this timeout constraint
65 * @param connectionTimeout The connection timeout in milliseconds.
66 */
67 public void setConnectionTimeout(final int connectionTimeout) {
68 this.connectionTimeout = connectionTimeout;
69 }
70
71 /**
72 * Sets the read timeout of this timeout constraint
73 * @param readTimeout The read timeout in milliseconds.
74 */
75 public void setReadTimeout(final int readTimeout) {
76 this.readTimeout = readTimeout;
77 }
78 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 package org.apache.ivy.core.settings;
19
20 /**
21 * Represents the timeouts that are applicable while dealing with resources.
22 * <p>
23 * An example of its usage is
24 * {@link org.apache.ivy.plugins.resolver.DependencyResolver dependency resolvers}
25 * when they are resolving module descriptor and/or are downloading the artifacts.
26 */
27 public interface TimeoutConstraint {
28
29 /**
30 * @return Returns the timeout, in milliseconds, that's to be used while establishing a
31 * connection to a resource. A value greater than zero indicates the specific timeout to be
32 * used. A value of 0 indicates no timeout and essentially translates to wait-forever
33 * semantics. A value lesser than 0 lets the users of this {@link TimeoutConstraint}
34 * decide what kind of timeout semantics to use while establishing a connection (for example,
35 * some implementations can decide to use some default value).
36 */
37 int getConnectionTimeout();
38
39 /**
40 * @return Returns the timeout, in milliseconds, that's to be used while reading content from
41 * a resource. A value greater than zero indicates the specific timeout to be used. A value of
42 * 0 indicates no timeout and essentially translates to wait-forever semantics. A value lesser
43 * than 0 lets the users of this {@link TimeoutConstraint} decide what kind of timeout
44 * semantics to use reading from the resource (for example, some implementations can decide to
45 * use some default value).
46 */
47 int getReadTimeout();
48
49 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 /**
2424 * Validates the Validatable, throwing an {@link IllegalStateException} if the current state is
2525 * not valid.
26 *
26 *
2727 * @throws IllegalStateException
2828 * if the state of the {@link Validatable} is not valid.
2929 */
30 public void validate();
30 void validate();
3131 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 import java.util.Arrays;
2929 import java.util.Collection;
3030 import java.util.HashMap;
31 import java.util.Iterator;
3231 import java.util.List;
3332 import java.util.Map;
3433
4746 import org.apache.ivy.util.FileResolver;
4847 import org.apache.ivy.util.Message;
4948 import org.apache.ivy.util.url.CredentialsStore;
50 import org.apache.ivy.util.url.URLHandler;
49 import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
5150 import org.apache.ivy.util.url.URLHandlerRegistry;
5251 import org.xml.sax.Attributes;
5352 import org.xml.sax.InputSource;
5453 import org.xml.sax.SAXException;
5554 import org.xml.sax.helpers.DefaultHandler;
55
56 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
5657
5758 /**
5859 */
6364 * propagated to the wrapped instance.
6465 */
6566 private static final class IvyVariableContainerWrapper implements IvyVariableContainer {
66 private static final Collection SETTINGS_VARIABLES = Arrays.asList(new String[] {
67 "ivy.settings.dir", "ivy.settings.url", "ivy.settings.file", "ivy.conf.dir",
68 "ivy.conf.url", "ivy.conf.file"});
67 private static final Collection<String> SETTINGS_VARIABLES = Arrays.asList(
68 "ivy.settings.dir", "ivy.settings.url", "ivy.settings.file", "ivy.conf.dir",
69 "ivy.conf.url", "ivy.conf.file");
6970
7071 private final IvyVariableContainer variables;
7172
72 private Map localVariables = new HashMap();
73 private Map<String, String> localVariables = new HashMap<>();
7374
7475 private IvyVariableContainerWrapper(IvyVariableContainer variables) {
7576 this.variables = variables;
9192
9293 public String getVariable(String name) {
9394 if (localVariables.containsKey(name)) {
94 return (String) localVariables.get(name);
95 return localVariables.get(name);
9596 }
9697 return variables.getVariable(name);
9798 }
103104
104105 private Configurator configurator;
105106
106 private List configuratorTags = Arrays.asList(new String[] {"resolvers", "namespaces",
107 "parsers", "latest-strategies", "conflict-managers", "outputters", "version-matchers",
108 "statuses", "circular-dependency-strategies", "triggers", "lock-strategies", "caches",
109 "signers"});
107 private List<String> configuratorTags = Arrays.asList("resolvers", "namespaces", "parsers",
108 "latest-strategies", "conflict-managers", "outputters", "version-matchers", "statuses",
109 "circular-dependency-strategies", "triggers", "lock-strategies", "caches", "signers", "timeout-constraints");
110110
111111 private IvySettings ivy;
112112
140140 }
141141 });
142142 // put every type definition from ivy to configurator
143 Map typeDefs = ivy.getTypeDefs();
144 for (Iterator iter = typeDefs.keySet().iterator(); iter.hasNext();) {
145 String name = (String) iter.next();
146 configurator.typeDef(name, (Class) typeDefs.get(name));
143 for (Map.Entry<String, Class<?>> entry : ivy.getTypeDefs().entrySet()) {
144 configurator.typeDef(entry.getKey(), entry.getValue());
147145 }
148146
149147 doParse(settings);
150148 }
151149
150 @SuppressWarnings("deprecation")
152151 private void doParse(URL settingsUrl) throws IOException, ParseException {
153152 this.settings = settingsUrl;
154 InputStream stream = null;
155 try {
156 stream = URLHandlerRegistry.getDefault().openStream(settingsUrl);
153 try (InputStream stream = URLHandlerRegistry.getDefault().openStream(settingsUrl)) {
157154 InputSource inSrc = new InputSource(stream);
158155 inSrc.setSystemId(settingsUrl.toExternalForm());
159156 SAXParserFactory.newInstance().newSAXParser().parse(settingsUrl.toExternalForm(), this);
165162 + ": " + e.getMessage(), 0);
166163 pe.initCause(e);
167164 throw pe;
168 } finally {
169 if (stream != null) {
170 try {
171 stream.close();
172 } catch (IOException e) {
173 // ignored
174 }
175 }
176165 }
177166 }
178167
182171 doParse(configuration);
183172 }
184173
174 @Override
185175 public void startElement(String uri, String localName, String qName, Attributes att)
186176 throws SAXException {
187177 // we first copy attributes in a Map to be able to modify them
188 Map attributes = new HashMap();
178 Map<String, String> attributes = new HashMap<>();
189179 for (int i = 0; i < att.getLength(); i++) {
190180 attributes.put(att.getQName(i), ivy.substitute(att.getValue(i)));
191181 }
226216 credentialsStarted(attributes);
227217 }
228218 } catch (ParseException ex) {
229 SAXException sax = new SAXException("problem in config file: " + ex.getMessage(), ex);
230 sax.initCause(ex);
231 throw sax;
219 throw new SAXException("problem in config file: " + ex.getMessage(), ex);
232220 } catch (IOException ex) {
233 SAXException sax = new SAXException("io problem while parsing config file: "
234 + ex.getMessage(), ex);
235 sax.initCause(ex);
236 throw sax;
237 }
238 }
239
240 private void credentialsStarted(Map attributes) {
241 String realm = (String) attributes.remove("realm");
242 String host = (String) attributes.remove("host");
243 String userName = (String) attributes.remove("username");
244 String passwd = (String) attributes.remove("passwd");
221 throw new SAXException("io problem while parsing config file: " + ex.getMessage(), ex);
222 }
223 }
224
225 private void credentialsStarted(Map<String, String> attributes) {
226 String realm = attributes.remove("realm");
227 String host = attributes.remove("host");
228 String userName = attributes.remove("username");
229 String passwd = attributes.remove("passwd");
245230 CredentialsStore.INSTANCE.addCredentials(realm, host, userName, passwd);
246231 }
247232
248 private void moduleStarted(Map attributes) {
233 private void moduleStarted(Map<String, String> attributes) {
249234 attributes.put(IvyPatternHelper.MODULE_KEY, attributes.remove("name"));
250 String resolver = (String) attributes.remove("resolver");
251 String branch = (String) attributes.remove("branch");
252 String cm = (String) attributes.remove("conflict-manager");
253 String resolveMode = (String) attributes.remove("resolveMode");
254 String matcher = (String) attributes.remove("matcher");
255 matcher = matcher == null ? PatternMatcher.EXACT_OR_REGEXP : matcher;
235 String resolver = attributes.remove("resolver");
236 String branch = attributes.remove("branch");
237 String cm = attributes.remove("conflict-manager");
238 String resolveMode = attributes.remove("resolveMode");
239 String matcher = attributes.remove("matcher");
240 matcher = (matcher == null) ? PatternMatcher.EXACT_OR_REGEXP : matcher;
256241 ivy.addModuleConfiguration(attributes, ivy.getMatcher(matcher), resolver, branch, cm,
257242 resolveMode);
258243 }
259244
260 private void macrodefStarted(String qName, Map attributes) {
245 private void macrodefStarted(String qName, Map<String, String> attributes) {
261246 currentConfiguratorTag = qName;
262 Configurator.MacroDef macrodef = configurator
263 .startMacroDef((String) attributes.get("name"));
247 Configurator.MacroDef macrodef = configurator.startMacroDef(attributes.get("name"));
264248 macrodef.addAttribute("name", null);
265249 }
266250
269253 configurator.setRoot(ivy);
270254 }
271255
272 private void statusesStarted(String qName, Map attributes) {
256 private void statusesStarted(String qName, Map<String, String> attributes) {
273257 currentConfiguratorTag = qName;
274258 StatusManager m = new StatusManager();
275 String defaultStatus = (String) attributes.get("default");
259 String defaultStatus = attributes.get("default");
276260 if (defaultStatus != null) {
277261 m.setDefaultStatus(defaultStatus);
278262 }
280264 configurator.setRoot(m);
281265 }
282266
283 private void versionMatchersStarted(String qName, Map attributes) {
267 private void versionMatchersStarted(String qName, Map<String, String> attributes) {
284268 anyConfiguratorStarted(qName);
285269 if ("true".equals(attributes.get("usedefaults"))) {
286270 ivy.configureDefaultVersionMatcher();
287271 }
288272 }
289273
290 private void cachesStarted(String qName, Map attributes) {
274 private void cachesStarted(String qName, Map<String, String> attributes) {
291275 anyConfiguratorStarted(qName);
292 defaultLock = (String) attributes.get("lockStrategy");
293 defaultCacheManager = (String) attributes.get("default");
294
295 String cache = (String) attributes.get("defaultCacheDir");
276 defaultLock = attributes.get("lockStrategy");
277 defaultCacheManager = attributes.get("default");
278
279 String cache = attributes.get("defaultCacheDir");
296280 if (cache != null) {
297281 ivy.setDefaultCache(Checks.checkAbsolute(cache, "defaultCacheDir"));
298282 }
299 String up2d = (String) attributes.get("checkUpToDate");
283 String up2d = attributes.get("checkUpToDate");
300284 if (up2d != null) {
301285 Message.deprecated("'checkUpToDate' is deprecated, "
302286 + "use the 'overwriteMode' on the 'ivy:retrieve' task instead (" + settings
303287 + ")");
304 ivy.setCheckUpToDate(Boolean.valueOf(up2d).booleanValue());
305 }
306 String resolutionDir = (String) attributes.get("resolutionCacheDir");
288 ivy.setCheckUpToDate(Boolean.valueOf(up2d));
289 }
290 String resolutionDir = attributes.get("resolutionCacheDir");
307291 if (resolutionDir != null) {
308292 ivy.setDefaultResolutionCacheBasedir(resolutionDir);
309293 }
310 String useOrigin = (String) attributes.get("useOrigin");
294 String useOrigin = attributes.get("useOrigin");
311295 if (useOrigin != null) {
312 ivy.setDefaultUseOrigin(Boolean.valueOf(useOrigin).booleanValue());
313 }
314 String cacheIvyPattern = (String) attributes.get("ivyPattern");
296 ivy.setDefaultUseOrigin(Boolean.valueOf(useOrigin));
297 }
298 String cacheIvyPattern = attributes.get("ivyPattern");
315299 if (cacheIvyPattern != null) {
316300 ivy.setDefaultCacheIvyPattern(cacheIvyPattern);
317301 }
318 String cacheArtPattern = (String) attributes.get("artifactPattern");
302 String cacheArtPattern = attributes.get("artifactPattern");
319303 if (cacheArtPattern != null) {
320304 ivy.setDefaultCacheArtifactPattern(cacheArtPattern);
321305 }
322 String repositoryDir = (String) attributes.get("repositoryCacheDir");
306 String repositoryDir = attributes.get("repositoryCacheDir");
323307 if (repositoryDir != null) {
324308 ivy.setDefaultRepositoryCacheBasedir(repositoryDir);
325309 }
326310 }
327311
328 private void settingsStarted(String qName, Map attributes) {
312 @SuppressWarnings("deprecation")
313 private void settingsStarted(String qName, Map<String, String> attributes) {
329314 if ("conf".equals(qName) && !deprecatedMessagePrinted) {
330315 Message.deprecated("'conf' is deprecated, use 'settings' instead (" + settings + ")");
331316 }
332 String cache = (String) attributes.get("defaultCache");
317 String cache = attributes.get("defaultCache");
333318 if (cache != null) {
334319 Message.deprecated("'defaultCache' is deprecated, "
335320 + "use 'caches[@defaultCacheDir]' instead (" + settings + ")");
336321 ivy.setDefaultCache(Checks.checkAbsolute(cache, "defaultCache"));
337322 }
338 String defaultBranch = (String) attributes.get("defaultBranch");
323 String defaultBranch = attributes.get("defaultBranch");
339324 if (defaultBranch != null) {
340325 ivy.setDefaultBranch(defaultBranch);
341326 }
342 String defaultResolveMode = (String) attributes.get("defaultResolveMode");
327 String defaultResolveMode = attributes.get("defaultResolveMode");
343328 if (defaultResolveMode != null) {
344329 ivy.setDefaultResolveMode(defaultResolveMode);
345330 }
346 String validate = (String) attributes.get("validate");
331 String validate = attributes.get("validate");
347332 if (validate != null) {
348 ivy.setValidate(Boolean.valueOf(validate).booleanValue());
349 }
350 String up2d = (String) attributes.get("checkUpToDate");
333 ivy.setValidate(Boolean.valueOf(validate));
334 }
335 String up2d = attributes.get("checkUpToDate");
351336 if (up2d != null) {
352337 Message.deprecated("'checkUpToDate' is deprecated, "
353338 + "use the 'overwriteMode' on the 'ivy:retrieve' task instead (" + settings
354339 + ")");
355 ivy.setCheckUpToDate(Boolean.valueOf(up2d).booleanValue());
356 }
357 String useRemoteConfig = (String) attributes.get("useRemoteConfig");
340 ivy.setCheckUpToDate(Boolean.valueOf(up2d));
341 }
342 String useRemoteConfig = attributes.get("useRemoteConfig");
358343 if (useRemoteConfig != null) {
359 ivy.setUseRemoteConfig(Boolean.valueOf(useRemoteConfig).booleanValue());
360 }
361 String cacheIvyPattern = (String) attributes.get("cacheIvyPattern");
344 ivy.setUseRemoteConfig(Boolean.valueOf(useRemoteConfig));
345 }
346 String cacheIvyPattern = attributes.get("cacheIvyPattern");
362347 if (cacheIvyPattern != null) {
363348 Message.deprecated("'cacheIvyPattern' is deprecated, use 'caches[@ivyPattern]' instead"
364349 + " (" + settings + ")");
365350 ivy.setDefaultCacheIvyPattern(cacheIvyPattern);
366351 }
367 String cacheArtPattern = (String) attributes.get("cacheArtifactPattern");
352 String cacheArtPattern = attributes.get("cacheArtifactPattern");
368353 if (cacheArtPattern != null) {
369354 Message.deprecated("'cacheArtifactPattern' is deprecated, "
370355 + "use 'caches[@artifactPattern]' instead (" + settings + ")");
372357 }
373358
374359 // we do not set following defaults here since no instances has been registered yet
375 defaultResolver = (String) attributes.get("defaultResolver");
376 defaultCM = (String) attributes.get("defaultConflictManager");
377 defaultLatest = (String) attributes.get("defaultLatestStrategy");
378 defaultCircular = (String) attributes.get("circularDependencyStrategy");
379
380 String requestMethod = (String) attributes.get("httpRequestMethod");
360 defaultResolver = attributes.get("defaultResolver");
361 defaultCM = attributes.get("defaultConflictManager");
362 defaultLatest = attributes.get("defaultLatestStrategy");
363 defaultCircular = attributes.get("circularDependencyStrategy");
364
365 String requestMethod = attributes.get("httpRequestMethod");
381366 if ("head".equalsIgnoreCase(requestMethod)) {
382 URLHandlerRegistry.getHttp().setRequestMethod(URLHandler.REQUEST_METHOD_HEAD);
367 URLHandlerRegistry.getHttp().setRequestMethod(TimeoutConstrainedURLHandler.REQUEST_METHOD_HEAD);
383368 } else if ("get".equalsIgnoreCase(requestMethod)) {
384 URLHandlerRegistry.getHttp().setRequestMethod(URLHandler.REQUEST_METHOD_GET);
385 } else if ((requestMethod != null) && (requestMethod.trim().length() > 0)) {
386 throw new IllegalArgumentException("Invalid httpRequestMethod specified, must be "
387 + "one of {'HEAD', 'GET'}");
388 }
389 }
390
391 private void includeStarted(Map attributes) throws IOException, ParseException {
369 URLHandlerRegistry.getHttp().setRequestMethod(TimeoutConstrainedURLHandler.REQUEST_METHOD_GET);
370 } else if (!isNullOrEmpty(requestMethod)) {
371 throw new IllegalArgumentException(
372 "Invalid httpRequestMethod specified, must be one of {'HEAD', 'GET'}");
373 }
374 }
375
376 private void includeStarted(Map<String, String> attributes) throws IOException, ParseException {
392377 final IvyVariableContainer variables = ivy.getVariableContainer();
393378 ivy.setVariableContainer(new IvyVariableContainerWrapper(variables));
379 final boolean optionalInclude = "true".equals(attributes.get("optional"));
394380 try {
395 String propFilePath = (String) attributes.get("file");
381 String propFilePath = attributes.get("file");
396382 URL settingsURL = null;
397383 if (propFilePath == null) {
398 propFilePath = (String) attributes.get("url");
384 propFilePath = attributes.get("url");
399385 if (propFilePath == null) {
400386 throw new IllegalArgumentException(
401387 "bad include tag: specify file or url to include");
402388 } else {
403389 try {
404 // First asume that it is an absolute URL
405 settingsURL = new URL(propFilePath);
406 } catch (MalformedURLException e) {
407 // If that fail, it may be because it is a relative one.
408 settingsURL = new URL(this.settings, propFilePath);
390 try {
391 // First assume that it is an absolute URL
392 settingsURL = new URL(propFilePath);
393 } catch (MalformedURLException e) {
394 // If that fail, it may be because it is a relative one.
395 settingsURL = new URL(this.settings, propFilePath);
396 }
397 } catch (IOException ioe) {
398 if (!optionalInclude) {
399 throw ioe;
400 }
401 Message.verbose("Skipping inclusion of optional URL " + propFilePath
402 + " due to IOException - " + ioe.getMessage());
403 return;
409404 }
410405 Message.verbose("including url: " + settingsURL.toString());
411406 ivy.setSettingsVariables(settingsURL);
412407 }
413408 } else {
414 settingsURL = urlFromFileAttribute(propFilePath);
415 Message.verbose("including file: " + settingsURL);
416 if ("file".equals(settingsURL.getProtocol())) {
417 try {
418 File settingsFile = new File(new URI(settingsURL.toExternalForm()));
419 String optional = (String) attributes.get("optional");
420 if ("true".equals(optional) && !settingsFile.exists()) {
421 return;
409 try {
410 settingsURL = urlFromFileAttribute(propFilePath);
411 Message.verbose("including file: " + settingsURL);
412 if ("file".equals(settingsURL.getProtocol())) {
413 try {
414 File settingsFile = new File(new URI(settingsURL.toExternalForm()));
415 if (optionalInclude && !settingsFile.exists()) {
416 return;
417 }
418 ivy.setSettingsVariables(Checks.checkAbsolute(settingsFile,
419 "settings include path"));
420 } catch (URISyntaxException e) {
421 // try to make the best of it...
422 ivy.setSettingsVariables(Checks.checkAbsolute(settingsURL.getPath(),
423 "settings include path"));
422424 }
423
424 ivy.setSettingsVariables(Checks.checkAbsolute(settingsFile,
425 "settings include path"));
426 } catch (URISyntaxException e) {
427 // try to make the best of it...
428 ivy.setSettingsVariables(Checks.checkAbsolute(settingsURL.getPath(),
429 "settings include path"));
425 } else {
426 ivy.setSettingsVariables(settingsURL);
430427 }
431 } else {
432 ivy.setSettingsVariables(settingsURL);
433 }
434 }
435 new XmlSettingsParser(ivy).parse(configurator, settingsURL);
428 } catch (IOException ioe) {
429 if (!optionalInclude) {
430 throw ioe;
431 }
432 Message.verbose("Skipping inclusion of optional file " + propFilePath
433 + " due to IOException - " + ioe.getMessage());
434 return;
435 }
436 }
437 try {
438 new XmlSettingsParser(ivy).parse(configurator, settingsURL);
439 } catch (IOException ioe) {
440 if (!optionalInclude) {
441 throw ioe;
442 }
443 Message.verbose("Skipping inclusion of optional settings URL " + settingsURL
444 + " due to IOException - " + ioe.getMessage());
445 return;
446 }
436447 } finally {
437448 ivy.setVariableContainer(variables);
438449 }
471482 }
472483 }
473484
474 private void propertiesStarted(Map attributes) throws IOException {
475 String propFilePath = (String) attributes.get("file");
476 String environmentPrefix = (String) attributes.get("environment");
485 private void propertiesStarted(Map<String, String> attributes) throws IOException {
486 String propFilePath = attributes.get("file");
487 String environmentPrefix = attributes.get("environment");
477488 if (propFilePath != null) {
478 String overrideStr = (String) attributes.get("override");
479 boolean override = overrideStr == null ? true : Boolean.valueOf(overrideStr)
480 .booleanValue();
489 String overrideStr = attributes.get("override");
490 boolean override = (overrideStr == null) || Boolean.valueOf(overrideStr);
481491 Message.verbose("loading properties: " + propFilePath);
482492 try {
483493 URL fileUrl = urlFromFileAttribute(propFilePath);
493503 }
494504 }
495505
496 private void propertyStarted(Map attributes) {
497 String name = (String) attributes.get("name");
498 String value = (String) attributes.get("value");
499 String override = (String) attributes.get("override");
500 String isSetVar = (String) attributes.get("ifset");
501 String unlessSetVar = (String) attributes.get("unlessset");
506 private void propertyStarted(Map<String, String> attributes) {
507 String name = attributes.get("name");
508 String value = attributes.get("value");
509 String override = attributes.get("override");
510 String isSetVar = attributes.get("ifset");
511 String unlessSetVar = attributes.get("unlessset");
502512 if (name == null) {
503513 throw new IllegalArgumentException("missing attribute name on property tag");
504514 }
505515 if (value == null) {
506516 throw new IllegalArgumentException("missing attribute value on property tag");
507517 }
508 ivy.setVariable(name, value, override == null ? true : Boolean.valueOf(override)
509 .booleanValue(), isSetVar, unlessSetVar);
510 }
511
512 private void typedefStarted(Map attributes) {
513 String name = (String) attributes.get("name");
514 String className = (String) attributes.get("classname");
515 Class clazz = ivy.typeDef(name, className);
518 ivy.setVariable(name, value, (override == null) || Boolean.valueOf(override), isSetVar,
519 unlessSetVar);
520 }
521
522 private void typedefStarted(Map<String, String> attributes) {
523 String name = attributes.get("name");
524 String className = attributes.get("classname");
525 Class<?> clazz = ivy.typeDef(name, className);
516526 configurator.typeDef(name, clazz);
517527 }
518528
519 private void classpathStarted(Map attributes) throws IOException {
520 String urlStr = (String) attributes.get("url");
529 private void classpathStarted(Map<String, String> attributes) throws IOException {
530 String urlStr = attributes.get("url");
521531 URL url = null;
522532 if (urlStr == null) {
523 String file = (String) attributes.get("file");
533 String file = attributes.get("file");
524534 if (file == null) {
525535 throw new IllegalArgumentException(
526536 "either url or file should be given for classpath element");
533543 ivy.addClasspathURL(url);
534544 }
535545
536 private void inConfiguratorStarted(String qName, Map attributes) {
546 private void inConfiguratorStarted(String qName, Map<String, String> attributes) {
537547 if ("macrodef".equals(currentConfiguratorTag) && configurator.getTypeDef(qName) != null) {
538 String name = (String) attributes.get("name");
548 String name = attributes.get("name");
539549 if (name == null) {
540550 attributes.put("name", "@{name}");
541 } else if (name.indexOf("@{name}") != -1) {
551 } else if (name.contains("@{name}")) {
542552 attributes.put("name", name);
543553 } else {
544554 attributes.put("name", "@{name}-" + name);
549559 throw new IllegalArgumentException("ref attribute should be the only one ! found "
550560 + attributes.size() + " in " + qName);
551561 }
552 String name = (String) attributes.get("ref");
562 String name = attributes.get("ref");
553563 Object child = null;
554564 if ("resolvers".equals(currentConfiguratorTag) || "resolver".equals(qName)) {
555565 child = ivy.getResolver(name);
576586 configurator.addChild(qName, child);
577587 } else {
578588 configurator.startCreateChild(qName);
579 for (Iterator iter = attributes.keySet().iterator(); iter.hasNext();) {
580 String attName = (String) iter.next();
581 configurator.setAttribute(attName, (String) attributes.get(attName));
582 }
583 }
584 }
585
589 for (Map.Entry<String, String> attribute : attributes.entrySet()) {
590 configurator.setAttribute(attribute.getKey(), attribute.getValue());
591 }
592 }
593 }
594
595 @Override
586596 public void endElement(String uri, String localName, String qName) throws SAXException {
587597 if (configurator.getCurrent() != null) {
588598 if (configuratorTags.contains(qName) && configurator.getDepth() == 1) {
597607 }
598608 }
599609
610 @Override
600611 public void endDocument() throws SAXException {
601612 if (defaultResolver != null) {
602613 ivy.setDefaultResolver(ivy.substitute(defaultResolver));
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818 ivy.project.dir = ${basedir}
1919 ivy.lib.dir = ${ivy.project.dir}/lib
2020 ivy.build.artifacts.dir = ${ivy.project.dir}/build/artifacts
2121 ivy.distrib.dir = ${ivy.project.dir}/distrib
22
22
2323 ivy.resolver.default.check.modified = false
2424 ivy.default.always.check.exact.revision = false
2525
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <settings defaultResolver="default"/>
20 <resolvers>
21 <ivyrep name="public" ivyroot="http://ivyrep.jayasoft.org/" />
22 </resolvers>
23 <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
24 <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
25 <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
26 <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
19 <settings defaultResolver="default"/>
20 <resolvers>
21 <!-- TODO: This repo is no longer relevant and must be removed -->
22 <ivyrep name="public" ivyroot="https://ivyrep.jayasoft.org/"/>
23 </resolvers>
24 <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
25 <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
26 <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
27 <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
2728 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <resolvers>
20 <chain name="default" returnFirst="true" checkmodified="true">
21 <resolver ref="local"/>
22 <resolver ref="main"/>
23 </chain>
24 </resolvers>
19 <resolvers>
20 <chain name="default" returnFirst="true" checkmodified="true">
21 <resolver ref="local"/>
22 <resolver ref="main"/>
23 </chain>
24 </resolvers>
2525 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <property name="ivy.local.default.root" value="${ivy.default.ivy.user.dir}/local" override="false"/>
20 <property name="ivy.local.default.ivy.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
21 <property name="ivy.local.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
22 <resolvers>
23 <filesystem name="local">
24 <ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}" />
25 <artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
26 </filesystem>
27 </resolvers>
19 <property name="ivy.local.default.root" value="${ivy.default.ivy.user.dir}/local" override="false"/>
20 <property name="ivy.local.default.ivy.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
21 <property name="ivy.local.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
22 <resolvers>
23 <filesystem name="local">
24 <ivy pattern="${ivy.local.default.root}/${ivy.local.default.ivy.pattern}" />
25 <artifact pattern="${ivy.local.default.root}/${ivy.local.default.artifact.pattern}" />
26 </filesystem>
27 </resolvers>
2828 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <resolvers>
20 <chain name="main" dual="true">
21 <resolver ref="shared"/>
22 <resolver ref="public"/>
23 </chain>
24 </resolvers>
19 <resolvers>
20 <chain name="main" dual="true">
21 <resolver ref="shared"/>
22 <resolver ref="public"/>
23 </chain>
24 </resolvers>
2525 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <resolvers>
20 <ibiblio name="public" m2compatible="true"/>
21 </resolvers>
19 <resolvers>
20 <ibiblio name="public" m2compatible="true"/>
21 </resolvers>
2222 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <property name="ivy.shared.default.root" value="${ivy.default.ivy.user.dir}/shared" override="false"/>
20 <property name="ivy.shared.default.ivy.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
21 <property name="ivy.shared.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
22 <resolvers>
23 <filesystem name="shared">
24 <ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}" />
25 <artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}" />
26 </filesystem>
27 </resolvers>
19 <property name="ivy.shared.default.root" value="${ivy.default.ivy.user.dir}/shared" override="false"/>
20 <property name="ivy.shared.default.ivy.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
21 <property name="ivy.shared.default.artifact.pattern" value="[organisation]/[module]/[revision]/[type]s/[artifact].[ext]" override="false"/>
22 <resolvers>
23 <filesystem name="shared">
24 <ivy pattern="${ivy.shared.default.root}/${ivy.shared.default.ivy.pattern}" />
25 <artifact pattern="${ivy.shared.default.root}/${ivy.shared.default.artifact.pattern}" />
26 </filesystem>
27 </resolvers>
2828 </ivysettings>
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <ivysettings>
19 <settings defaultResolver="default"/>
20 <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
21 <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
22 <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
23 <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
24 <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
19 <settings defaultResolver="default"/>
20 <include url="${ivy.default.settings.dir}/ivysettings-public.xml"/>
21 <include url="${ivy.default.settings.dir}/ivysettings-shared.xml"/>
22 <include url="${ivy.default.settings.dir}/ivysettings-local.xml"/>
23 <include url="${ivy.default.settings.dir}/ivysettings-main-chain.xml"/>
24 <include url="${ivy.default.settings.dir}/ivysettings-default-chain.xml"/>
2525 </ivysettings>
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
18 ivy.ibiblio.default.artifact.root = http://www.ibiblio.org/maven/
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
18 ivy.ibiblio.default.artifact.root = https://repo1.maven.org/maven2/
1919 ivy.ibiblio.default.artifact.pattern = [module]/[type]s/[artifact]-[revision].[ext]
2020
2121 ivy.ivyrep.default.ivy.pattern = [organisation]/[module]/ivy-[revision].xml
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
18 filesystem = org.apache.ivy.plugins.resolver.FileSystemResolver
19 chain = org.apache.ivy.plugins.resolver.ChainResolver
20 ibiblio = org.apache.ivy.plugins.resolver.IBiblioResolver
21 bintray = org.apache.ivy.plugins.resolver.BintrayResolver
22 url = org.apache.ivy.plugins.resolver.URLResolver
23 dual = org.apache.ivy.plugins.resolver.DualResolver
24 ivyrep = org.apache.ivy.plugins.resolver.IvyRepResolver
25 ssh = org.apache.ivy.plugins.resolver.SshResolver
26 sftp = org.apache.ivy.plugins.resolver.SFTPResolver
27 vsftp = org.apache.ivy.plugins.resolver.VsftpResolver
28 vfs = org.apache.ivy.plugins.resolver.VfsResolver
29 jar = org.apache.ivy.plugins.resolver.JarResolver
30 cache = org.apache.ivy.plugins.resolver.CacheResolver
31 packager = org.apache.ivy.plugins.resolver.packager.PackagerResolver
32 obr = org.apache.ivy.osgi.obr.OBRResolver
33 mirroredurl = org.apache.ivy.plugins.resolver.MirroredURLResolver
34 updatesite = org.apache.ivy.osgi.updatesite.UpdateSiteResolver
35 osgi-agg = org.apache.ivy.osgi.repo.AggregatedOSGiResolver
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
18 filesystem = org.apache.ivy.plugins.resolver.FileSystemResolver
19 chain = org.apache.ivy.plugins.resolver.ChainResolver
20 ibiblio = org.apache.ivy.plugins.resolver.IBiblioResolver
21 bintray = org.apache.ivy.plugins.resolver.BintrayResolver
22 url = org.apache.ivy.plugins.resolver.URLResolver
23 dual = org.apache.ivy.plugins.resolver.DualResolver
24 ivyrep = org.apache.ivy.plugins.resolver.IvyRepResolver
25 ssh = org.apache.ivy.plugins.resolver.SshResolver
26 sftp = org.apache.ivy.plugins.resolver.SFTPResolver
27 vsftp = org.apache.ivy.plugins.resolver.VsftpResolver
28 vfs = org.apache.ivy.plugins.resolver.VfsResolver
29 jar = org.apache.ivy.plugins.resolver.JarResolver
30 packager = org.apache.ivy.plugins.resolver.packager.PackagerResolver
31 obr = org.apache.ivy.osgi.obr.OBRResolver
32 mirroredurl = org.apache.ivy.plugins.resolver.MirroredURLResolver
33 updatesite = org.apache.ivy.osgi.updatesite.UpdateSiteResolver
34 osgi-agg = org.apache.ivy.osgi.repo.AggregatedOSGiResolver
3635
3736 latest-revision = org.apache.ivy.plugins.latest.LatestRevisionStrategy
3837 latest-lexico = org.apache.ivy.plugins.latest.LatestLexicographicStrategy
3938 latest-time = org.apache.ivy.plugins.latest.LatestTimeStrategy
4039
41 fixed-cm = org.apache.ivy.plugins.conflict.FixedConflictManager
42 latest-cm = org.apache.ivy.plugins.conflict.LatestConflictManager
40 fixed-cm = org.apache.ivy.plugins.conflict.FixedConflictManager
41 latest-cm = org.apache.ivy.plugins.conflict.LatestConflictManager
4342 compatible-cm = org.apache.ivy.plugins.conflict.LatestCompatibleConflictManager
44 no-cm = org.apache.ivy.plugins.conflict.NoConflictManager
45 strict-cm = org.apache.ivy.plugins.conflict.StrictConflictManager
46 regexp-cm = org.apache.ivy.plugins.conflict.RegexpConflictManager
43 no-cm = org.apache.ivy.plugins.conflict.NoConflictManager
44 strict-cm = org.apache.ivy.plugins.conflict.StrictConflictManager
45 regexp-cm = org.apache.ivy.plugins.conflict.RegexpConflictManager
4746
47 namespace = org.apache.ivy.plugins.namespace.Namespace
4848
49 namespace = org.apache.ivy.plugins.namespace.Namespace
49 exact-vm = org.apache.ivy.plugins.version.ExactVersionMatcher
50 chain-vm = org.apache.ivy.plugins.version.ChainVersionMatcher
51 latest-vm = org.apache.ivy.plugins.version.LatestVersionMatcher
52 sub-vm = org.apache.ivy.plugins.version.SubVersionMatcher
53 range-vm = org.apache.ivy.plugins.version.VersionRangeMatcher
54 pattern-vm = org.apache.ivy.plugins.version.PatternVersionMatcher
55 maven-tsnap-vm = org.apache.ivy.plugins.version.MavenTimedSnapshotVersionMatcher
5056
51 exact-vm = org.apache.ivy.plugins.version.ExactVersionMatcher
52 chain-vm = org.apache.ivy.plugins.version.ChainVersionMatcher
53 latest-vm = org.apache.ivy.plugins.version.LatestVersionMatcher
54 sub-vm = org.apache.ivy.plugins.version.SubVersionMatcher
55 range-vm = org.apache.ivy.plugins.version.VersionRangeMatcher
56 pattern-vm = org.apache.ivy.plugins.version.PatternVersionMatcher
57 ant-build = org.apache.ivy.ant.AntBuildTrigger
58 ant-call = org.apache.ivy.ant.AntCallTrigger
59 log = org.apache.ivy.plugins.trigger.LogTrigger
5760
58 ant-build = org.apache.ivy.ant.AntBuildTrigger
59 ant-call = org.apache.ivy.ant.AntCallTrigger
60 log = org.apache.ivy.plugins.trigger.LogTrigger
61
62 cache = org.apache.ivy.core.cache.DefaultRepositoryCacheManager
61 cache = org.apache.ivy.core.cache.DefaultRepositoryCacheManager
6362
6463 pgp = org.apache.ivy.plugins.signer.bouncycastle.OpenPGPSignatureGenerator
6564
6665 osgi-manifest-parser = org.apache.ivy.osgi.core.OSGiManifestParser
66
67 timeout-constraint = org.apache.ivy.core.settings.NamedTimeoutConstraint
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030 import org.apache.ivy.plugins.version.VersionMatcher;
3131
3232 /**
33 * Wrap a collection of descriptores wrapped themself in ModuleInSort elements. It contains some
34 * dedicated function to retrieve module descriptors based on dependencies descriptors.<br>
33 * Wrap a collection of descriptors wrapped themselves in ModuleInSort elements. It contains some
34 * dedicated function to retrieve module descriptors based on dependencies descriptors.
35 * <p>
3536 * <i>This class is designed to be used internally by the ModuleDescriptorSorter.</i>
37 * </p>
3638 */
3739 class CollectionOfModulesToSort implements Iterable<ModuleInSort> {
3840
5052 * @param matcher
5153 * The matcher to used to check if dependencyDescriptor match a module in this
5254 * collection
53 * @param nonMatchingVersionReporter
55 * @param nonMatchingVersionReporter ditto
5456 */
5557 public CollectionOfModulesToSort(Collection<ModuleDescriptor> modulesToSort,
5658 VersionMatcher matcher, NonMatchingVersionReporter nonMatchingVersionReporter) {
5759 this.versionMatcher = matcher;
5860 this.nonMatchingVersionReporter = nonMatchingVersionReporter;
59 this.modulesByModuleId = new HashMap<ModuleId, Collection<ModuleInSort>>();
60 moduleDescriptors = new ArrayList<ModuleInSort>(modulesToSort.size());
61 this.modulesByModuleId = new HashMap<>();
62 moduleDescriptors = new ArrayList<>(modulesToSort.size());
6163 for (ModuleDescriptor md : modulesToSort) {
6264 ModuleInSort mdInSort = new ModuleInSort(md);
6365 moduleDescriptors.add(mdInSort);
6769
6870 private void addToModulesByModuleId(ModuleDescriptor md, ModuleInSort mdInSort) {
6971 ModuleId mdId = md.getModuleRevisionId().getModuleId();
70 List<ModuleInSort> mdInSortAsList = new LinkedList<ModuleInSort>();
72 List<ModuleInSort> mdInSortAsList = new LinkedList<>();
7173 mdInSortAsList.add(mdInSort);
7274 Collection<ModuleInSort> previousList = modulesByModuleId.put(mdId, mdInSortAsList);
7375 if (previousList != null) {
8587
8688 /**
8789 * Find a matching module descriptor in the list of module to sort.
88 *
89 * @param descriptor
90 *
91 * @param descriptor ditto
9092 * @return a ModuleDescriptor from the collection of module descriptors to sort. If none exists
9193 * returns null.
9294 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 import org.apache.ivy.util.Message;
2929
3030 /**
31 * Inner helper class for sorting ModuleDescriptors.<br>
31 * Inner helper class for sorting ModuleDescriptors.
32 * <p>
3233 * ModuleDescriptorSorter use CollectionOfModulesToSort to find the dependencies of the modules, and
3334 * use ModuleInSort to store some temporary values attached to the modules to sort.
34 *
35 * </p>
36 *
3537 * @see ModuleInSort
3638 * @see CollectionOfModulesToSort
3739 */
3941
4042 private final CollectionOfModulesToSort moduleDescriptors;
4143
42 private final List<ModuleDescriptor> sorted = new LinkedList<ModuleDescriptor>();
44 private final List<ModuleDescriptor> sorted = new LinkedList<>();
4345
4446 private final CircularDependencyStrategy circularDepStrategy;
4547
5355
5456 /**
5557 * Iterates over all modules calling sortModuleDescriptorsHelp.
56 *
58 *
5759 * @return sorted module
58 * @throws CircularDependencyException
60 * @throws CircularDependencyException somehow
5961 */
6062 public List<ModuleDescriptor> sortModuleDescriptors() throws CircularDependencyException {
6163 Message.debug("Nbr of module to sort : " + moduleDescriptors.size());
7274 * When a loop is detected by a recursive call, the moduleDescriptors are not added immediately
7375 * added to the sorted list. They are added as loop dependencies of the root, and will be added
7476 * to the sorted list only when the root itself will be added.
75 *
77 *
7678 * @param current
7779 * Current module to add to sorted list.
78 * @throws CircularDependencyException
80 * @throws CircularDependencyException somehow
7981 */
8082 private void sortModuleDescriptorsHelp(ModuleInSort current, ModuleInSort caller)
8183 throws CircularDependencyException {
9092 Message.debug("Sort dependencies of : " + current.toString()
9193 + " / Number of dependencies = " + descriptors.length);
9294 current.setCaller(caller);
93 for (int i = 0; i < descriptors.length; i++) {
94 ModuleInSort child = moduleDescriptors.getModuleDescriptorDependency(descriptors[i]);
95 for (DependencyDescriptor descriptor : descriptors) {
96 ModuleInSort child = moduleDescriptors.getModuleDescriptorDependency(descriptor);
9597 if (child != null) {
9698 sortModuleDescriptorsHelp(child, current);
9799 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030
3131 /**
3232 * Decorates a ModuleDescriptor with some attributes used during the sort. Thus every instance of a
33 * ModuleInSort can be used in only one ModuleDescriptorSorter at a time.<br>
34 * The added fields are : <br>
33 * ModuleInSort can be used in only one ModuleDescriptorSorter at a time.
34 * <p>
35 * The added fields are:
36 * </p>
3537 * <ul>
36 * <li><code>isSorted</code> : is true iff this module has already been added to the sorted list.</li>
38 * <li><code>isSorted</code> : is <i>true</i> if and only if this module has already been added to
39 * the sorted list.</li>
3740 * <li><code>loopElements</code> : When the module is the root of a loop (=the first element of a
38 * loop met during the sort), <code>loopElements</code> contains all ModuleInSort of the loop
39 * (excluding the root itself.</li>
40 * <li><code>isLoopIntermediateElement</code> : When a loop is detected, all modules included in the
41 * loop (except the root) have <code>isLoopIntermediateElement</code> set to true.</li>
41 * loop met during the sort), <code>loopElements</code> contains all ModuleInSort of the loop
42 * (excluding the root itself.</li>
43 * <li><code>isLoopIntermediateElement</code> : When a loop is detected, all modules included in
44 * the loop (except the root) have <code>isLoopIntermediateElement</code> set to true.</li>
4245 * <li><code>caller</code> : During the sort, we traverse recursively the graph. When doing that,
43 * caller point to the parent element.
46 * caller point to the parent element.</li>
47 * </ul>
4448 */
4549 class ModuleInSort {
4650
4852
4953 private boolean isSorted = false;
5054
51 private List<ModuleInSort> loopElements = new LinkedList<ModuleInSort>();
55 private List<ModuleInSort> loopElements = new LinkedList<>();
5256
5357 private boolean isLoopIntermediateElement = false;
5458
98102
99103 /**
100104 * Check if a adding this element as a dependency of caller will introduce a circular
101 * dependency. If it is, all the elements of the loop are flaged as 'loopIntermediateElement',
105 * dependency. If it is, all the elements of the loop are flagged as 'loopIntermediateElement',
102106 * and the loopElements of this module (which is the root of the loop) is updated. The
103107 * depStrategy is invoked on order to report a correct circular loop message.
104 *
105 * @param futurCaller
106 * @param depStrategy
108 *
109 * @param futurCaller ModuleInSort
110 * @param depStrategy CircularDependencyStrategy
107111 * @return true if a loop is detected.
108112 */
109113 public boolean checkLoop(ModuleInSort futurCaller, CircularDependencyStrategy depStrategy) {
110114 if (caller != null) {
111 LinkedList<ModuleRevisionId> elemOfLoop = new LinkedList<ModuleRevisionId>();
115 List<ModuleRevisionId> elemOfLoop = new LinkedList<>();
112116 elemOfLoop.add(this.module.getModuleRevisionId());
113 for (ModuleInSort stackEl = futurCaller; stackEl != this; stackEl = stackEl.caller) {
117 ModuleInSort stackEl = futurCaller;
118 while (stackEl != this) {
114119 elemOfLoop.add(stackEl.module.getModuleRevisionId());
115120 stackEl.isLoopIntermediateElement = true;
116121 loopElements.add(stackEl);
122 stackEl = stackEl.caller;
117123 }
118124 elemOfLoop.add(this.module.getModuleRevisionId());
119125 ModuleRevisionId[] mrids = elemOfLoop.toArray(new ModuleRevisionId[elemOfLoop.size()]);
128134 * Add this module to the sorted list except if this module is an intermediary element of a
129135 * loop. If this module is the 'root' of a loop, then all elements of that loops are added
130136 * before.
131 *
137 *
132138 * @param sorted
133139 * The list of sorted elements on which this module will be added
134140 */
161167 }
162168
163169 /** Log a warning saying that a loop is detected */
164 public static void logLoopWarning(List loopElement) {
170 public static void logLoopWarning(List<ModuleDescriptor> loopElement) {
165171 Message.warn("circular dependency detected during sort: "
166172 + CircularDependencyHelper.formatMessageFromDescriptors(loopElement));
167173 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 /**
2525 * Report to the user that ivy has detected that a module to sort has a dependency on an other
2626 * module to sort, but the revisions doesn't match.
27 *
27 *
2828 * @param descriptor
2929 * The non matching dependency descriptor.
3030 * @param md
31 * The module to sort having the corect moduleID but a non matching revision
31 * The module to sort having the correct moduleID but a non matching revision
3232 */
33 public void reportNonMatchingVersion(DependencyDescriptor descriptor, ModuleDescriptor md);
33 void reportNonMatchingVersion(DependencyDescriptor descriptor, ModuleDescriptor md);
3434
3535 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4444 /**
4545 * Same as {@link #sortModuleDescriptors(Collection, SortOptions)} but for <code>IvyNode</code>
4646 * s.
47 *
47 *
4848 * @param nodes
4949 * a Collection of nodes to sort
5050 * @param options
6262 * corresponding dependency
6363 */
6464
65 Map<ModuleDescriptor, List<IvyNode>> dependenciesMap = new LinkedHashMap<ModuleDescriptor, List<IvyNode>>();
66 List<IvyNode> nulls = new ArrayList<IvyNode>();
65 Map<ModuleDescriptor, List<IvyNode>> dependenciesMap = new LinkedHashMap<>();
66 List<IvyNode> nulls = new ArrayList<>();
6767 for (IvyNode node : nodes) {
6868 if (node.getDescriptor() == null) {
6969 nulls.add(node);
7070 } else {
7171 List<IvyNode> n = dependenciesMap.get(node.getDescriptor());
7272 if (n == null) {
73 n = new ArrayList<IvyNode>();
73 n = new ArrayList<>();
7474 dependenciesMap.put(node.getDescriptor(), n);
7575 }
7676 n.add(node);
7878 }
7979 List<ModuleDescriptor> list = sortModuleDescriptors(dependenciesMap.keySet(), options);
8080 final double adjustFactor = 1.3;
81 List<IvyNode> ret = new ArrayList<IvyNode>(
81 List<IvyNode> ret = new ArrayList<>(
8282 (int) (list.size() * adjustFactor + nulls.size()));
8383 // attempt to adjust the size to avoid too much list resizing
84 for (int i = 0; i < list.size(); i++) {
85 ModuleDescriptor md = list.get(i);
84 for (ModuleDescriptor md : list) {
8685 List<IvyNode> n = dependenciesMap.get(md);
8786 ret.addAll(n);
8887 }
9493 * Sorts the given ModuleDescriptors from the less dependent to the more dependent. This sort
9594 * ensures that a ModuleDescriptor is always found in the list before all ModuleDescriptors
9695 * depending directly on it.
97 *
96 *
9897 * @param moduleDescriptors
9998 * a Collection of ModuleDescriptor to sort
10099 * @param options
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 */
2525 public interface SortEngineSettings {
2626
27 public CircularDependencyStrategy getCircularDependencyStrategy();
27 CircularDependencyStrategy getCircularDependencyStrategy();
2828
29 public VersionMatcher getVersionMatcher();
29 VersionMatcher getVersionMatcher();
3030 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
7878 } else if (!name.equals(other.name)) {
7979 return false;
8080 }
81 if (version == null) {
82 if (other.version != null) {
83 return false;
84 }
85 } else if (!version.equals(other.version)) {
86 return false;
87 }
88 return true;
81 return version == null ? other.version == null : version.equals(other.version);
8982 }
9083
91 }
84 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525
2626 /**
2727 * Bundle info extracted from the bundle manifest.
28 *
28 *
2929 */
3030 public class BundleInfo {
3131
4747
4848 private Version version;
4949
50 private Set<BundleRequirement> requirements = new LinkedHashSet<BundleRequirement>();
51
52 private Set<BundleCapability> capabilities = new LinkedHashSet<BundleCapability>();
53
54 private List<String> executionEnvironments = new ArrayList<String>();
50 private Set<BundleRequirement> requirements = new LinkedHashSet<>();
51
52 private Set<BundleCapability> capabilities = new LinkedHashSet<>();
53
54 private List<String> executionEnvironments = new ArrayList<>();
5555
5656 private String description;
5757
7373
7474 private List<String> classpath;
7575
76 private List<BundleArtifact> artifacts = new ArrayList<BundleArtifact>();
76 private List<BundleArtifact> artifacts = new ArrayList<>();
7777
7878 public BundleInfo(String name, Version version) {
7979 this.symbolicName = name;
8181 }
8282
8383 public String toString() {
84 StringBuffer builder = new StringBuffer();
84 StringBuilder builder = new StringBuilder();
8585 builder.append("BundleInfo [executionEnvironments=");
8686 builder.append(executionEnvironments);
8787 builder.append(", capabilities=");
324324 } else if (!versionTarget.equals(other.versionTarget)) {
325325 return false;
326326 }
327 if (hasInnerClasspath != other.hasInnerClasspath) {
328 return false;
329 }
330 if (classpath == null) {
331 if (other.classpath != null) {
332 return false;
333 }
334 } else if (!classpath.equals(other.classpath)) {
335 return false;
336 }
337 return true;
327 return hasInnerClasspath == other.hasInnerClasspath
328 && (classpath == null ? other.classpath == null : classpath.equals(other.classpath));
338329 }
339330
340331 public Set<BundleRequirement> getRequires() {
341 Set<BundleRequirement> set = new LinkedHashSet<BundleRequirement>();
332 Set<BundleRequirement> set = new LinkedHashSet<>();
342333 for (BundleRequirement requirement : requirements) {
343334 if (requirement.getType().equals(BUNDLE_TYPE)) {
344335 set.add(requirement);
348339 }
349340
350341 public Set<BundleRequirement> getImports() {
351 Set<BundleRequirement> set = new LinkedHashSet<BundleRequirement>();
342 Set<BundleRequirement> set = new LinkedHashSet<>();
352343 for (BundleRequirement requirement : requirements) {
353344 if (requirement.getType().equals(PACKAGE_TYPE)) {
354345 set.add(requirement);
358349 }
359350
360351 public Set<ExportPackage> getExports() {
361 Set<ExportPackage> set = new LinkedHashSet<ExportPackage>();
352 Set<ExportPackage> set = new LinkedHashSet<>();
362353 for (BundleCapability capability : capabilities) {
363354 if (PACKAGE_TYPE.equals(capability.getType())) {
364355 set.add((ExportPackage) capability);
368359 }
369360
370361 public Set<BundleCapability> getServices() {
371 Set<BundleCapability> set = new LinkedHashSet<BundleCapability>();
362 Set<BundleCapability> set = new LinkedHashSet<>();
372363 for (BundleCapability capability : capabilities) {
373364 if (SERVICE_TYPE.equals(capability.getType())) {
374365 set.add(capability);
377368 return set;
378369 }
379370
380 }
371 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import java.util.HashSet;
2727 import java.util.List;
2828 import java.util.Map;
29 import java.util.Map.Entry;
3029 import java.util.Set;
3130 import java.util.jar.Manifest;
3231
3332 import org.apache.ivy.Ivy;
3433 import org.apache.ivy.core.module.descriptor.Artifact;
3534 import org.apache.ivy.core.module.descriptor.Configuration;
36 import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
3735 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
3836 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
3937 import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
4846 import org.apache.ivy.plugins.matcher.PatternMatcher;
4947 import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
5048
49 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
50
5151 public class BundleInfoAdapter {
5252
5353 public static final String CONF_NAME_DEFAULT = "default";
5757 public static final String CONF_NAME_OPTIONAL = "optional";
5858
5959 public static final Configuration CONF_OPTIONAL = new Configuration(CONF_NAME_OPTIONAL,
60 Visibility.PUBLIC, "Optional dependencies", new String[] {CONF_NAME_DEFAULT}, true,
60 PUBLIC, "Optional dependencies", new String[] {CONF_NAME_DEFAULT}, true,
6161 null);
6262
6363 public static final String CONF_NAME_TRANSITIVE_OPTIONAL = "transitive-optional";
6464
6565 public static final Configuration CONF_TRANSITIVE_OPTIONAL = new Configuration(
66 CONF_NAME_TRANSITIVE_OPTIONAL, Visibility.PUBLIC, "Optional dependencies",
66 CONF_NAME_TRANSITIVE_OPTIONAL, PUBLIC, "Optional dependencies",
6767 new String[] {CONF_NAME_OPTIONAL}, true, null);
6868
6969 public static final String CONF_USE_PREFIX = "use_";
7676 }
7777
7878 /**
79 *
79 * @param parser ModuleDescriptorParser
8080 * @param baseUri
8181 * uri to help build the absolute url if the bundle info has a relative uri.
82 * @return
83 * @throws ProfileNotFoundException
82 * @param bundle BundleInfo
83 * @param manifest Manifest
84 * @param profileProvider ExecutionEnvironmentProfileProvider
85 * @return DefaultModuleDescriptor ditto
86 * @throws ProfileNotFoundException if descriptor is not found
8487 */
8588 public static DefaultModuleDescriptor toModuleDescriptor(ModuleDescriptorParser parser,
8689 URI baseUri, BundleInfo bundle, Manifest manifest,
9699 md.addConfiguration(CONF_OPTIONAL);
97100 md.addConfiguration(CONF_TRANSITIVE_OPTIONAL);
98101
99 Set<String> exportedPkgNames = new HashSet<String>(bundle.getExports().size());
102 Set<String> exportedPkgNames = new HashSet<>(bundle.getExports().size());
100103 for (ExportPackage exportPackage : bundle.getExports()) {
101104 md.getExtraInfos().add(
102105 new ExtraInfoHolder(EXTRA_INFO_EXPORT_PREFIX + exportPackage.getName(),
109112 }
110113 confDependencies[i] = CONF_NAME_DEFAULT;
111114 md.addConfiguration(new Configuration(CONF_USE_PREFIX + exportPackage.getName(),
112 Visibility.PUBLIC, "Exported package " + exportPackage.getName(),
115 PUBLIC, "Exported package " + exportPackage.getName(),
113116 confDependencies, true, null));
114117 }
115118
156159 PatternMatcher.ANY_EXPRESSION);
157160 DefaultExcludeRule rule = new DefaultExcludeRule(id,
158161 ExactOrRegexpPatternMatcher.INSTANCE, null);
159 String[] confs = md.getConfigurationsNames();
160 for (int i = 0; i < confs.length; i++) {
161 rule.addConfiguration(confs[i]);
162 for (String conf : md.getConfigurationsNames()) {
163 rule.addConfiguration(conf);
162164 }
163165 md.addExcludeRule(rule);
164166 }
166168 }
167169
168170 if (manifest != null) {
169 for (Entry<Object, Object> entries : manifest.getMainAttributes().entrySet()) {
171 for (Map.Entry<Object, Object> entries : manifest.getMainAttributes().entrySet()) {
170172 md.addExtraInfo(new ExtraInfoHolder(entries.getKey().toString(), entries.getValue()
171173 .toString()));
172174 }
184186 if (!uri.isAbsolute()) {
185187 uri = baseUri.resolve(uri);
186188 }
187 Map<String, String> extraAtt = new HashMap<String, String>();
189 Map<String, String> extraAtt = new HashMap<>();
188190 if (packaging != null) {
189191 extraAtt.put("packaging", packaging);
190192 }
199201 }
200202
201203 public static List<String> getConfigurations(BundleInfo bundle) {
202 List<String> confs = new ArrayList<String>();
204 List<String> confs = new ArrayList<>();
203205 confs.add(CONF_NAME_DEFAULT);
204206 confs.add(CONF_NAME_OPTIONAL);
205207 confs.add(CONF_NAME_TRANSITIVE_OPTIONAL);
219221
220222 private static URI asIvyURI(String org, String name, String branch, String rev, String type,
221223 String art, String ext) {
222 StringBuffer builder = new StringBuffer();
223 builder.append("ivy:///");
224 builder.append(org);
225 builder.append('/');
226 builder.append(name);
227 builder.append('?');
224 StringBuilder builder = new StringBuilder();
225 builder.append("ivy:///").append(org).append('/').append(name).append('?');
228226 if (branch != null) {
229 builder.append("branch=");
230 builder.append(branch);
227 builder.append("branch=").append(branch);
231228 }
232229 if (rev != null) {
233 builder.append("&rev=");
234 builder.append(rev);
230 builder.append("&rev=").append(rev);
235231 }
236232 if (type != null) {
237 builder.append("&type=");
238 builder.append(type);
233 builder.append("&type=").append(type);
239234 }
240235 if (art != null) {
241 builder.append("&art=");
242 builder.append(art);
236 builder.append("&art=").append(art);
243237 }
244238 if (ext != null) {
245 builder.append("&ext=");
246 builder.append(ext);
239 builder.append("&ext=").append(ext);
247240 }
248241 try {
249242 return new URI(builder.toString());
250243 } catch (URISyntaxException e) {
251 throw new RuntimeException("illformed ivy url", e);
244 throw new RuntimeException("ill-formed ivy url", e);
252245 }
253246 }
254247
273266 org = path.substring(1, i);
274267 name = path.substring(i + 1);
275268
276 String query = uri.getQuery();
277 String[] parameters = query.split("&");
278 for (int j = 0; j < parameters.length; j++) {
279 String parameter = parameters[j];
269 for (String parameter : uri.getQuery().split("&")) {
280270 if (parameter.length() == 0) {
281271 continue;
282272 }
300290 }
301291
302292 ModuleRevisionId amrid = ModuleRevisionId.newInstance(org, name, branch, rev);
303 DefaultArtifact artifact = new DefaultArtifact(amrid, null, art, type, ext);
304 return artifact;
293 return new DefaultArtifact(amrid, null, art, type, ext);
305294 }
306295
307296 private static void requirementAsDependency(DefaultModuleDescriptor md, BundleInfo bundleInfo,
327316 if (BundleInfo.PACKAGE_TYPE.equals(type)) {
328317 // declare the configuration for the package
329318 conf = CONF_USE_PREFIX + name;
330 md.addConfiguration(new Configuration(CONF_USE_PREFIX + name, Visibility.PUBLIC,
319 md.addConfiguration(new Configuration(CONF_USE_PREFIX + name, PUBLIC,
331320 "Exported package " + name, new String[] {CONF_NAME_DEFAULT}, true, null));
332321 dd.addDependencyConfiguration(conf, conf);
333322 }
359348 return ModuleRevisionId.newInstance(type, name, revision);
360349 }
361350
351 @SuppressWarnings("serial")
362352 public static class ProfileNotFoundException extends RuntimeException {
363353
364354 public ProfileNotFoundException(String msg) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
9898 } else if (!resolution.equals(other.resolution)) {
9999 return false;
100100 }
101 if (version == null) {
102 if (other.version != null) {
103 return false;
104 }
105 } else if (!version.equals(other.version)) {
106 return false;
107 }
108 return true;
101 return version == null ? other.version == null : version.equals(other.version);
109102 }
110 }
103 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 public class ExecutionEnvironmentProfile {
2323
24 Set<String> pkgNames = new TreeSet<String>();
24 Set<String> pkgNames = new TreeSet<>();
2525
2626 private final String name;
2727
6363 } else if (!name.equals(other.name)) {
6464 return false;
6565 }
66 if (pkgNames == null) {
67 if (other.pkgNames != null) {
68 return false;
69 }
70 } else if (!pkgNames.equals(other.pkgNames)) {
71 return false;
72 }
73 return true;
66 return pkgNames == null ? other.pkgNames == null : pkgNames.equals(other.pkgNames);
7467 }
7568
7669 public String toString() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.InputStream;
2222 import java.util.HashMap;
2323 import java.util.Map;
24 import java.util.Map.Entry;
2524 import java.util.Properties;
2625
2726 import org.apache.ivy.util.Message;
27
28 import static org.apache.ivy.util.StringUtils.splitToArray;
2829
2930 public class ExecutionEnvironmentProfileProvider {
3031
7172 } finally {
7273 defaultProfilesFile.close();
7374 }
74 Map<String, ExecutionEnvironmentProfile> profiles = new HashMap<String, ExecutionEnvironmentProfile>();
75 for (Entry<Object, Object> prop : props.entrySet()) {
75 Map<String, ExecutionEnvironmentProfile> profiles = new HashMap<>();
76 for (Map.Entry<Object, Object> prop : props.entrySet()) {
7677 String propName = (String) prop.getKey();
7778 if (propName.endsWith(".pkglist")) {
7879 String profileName = propName.substring(0, propName.length() - 8);
102103
103104 // load the actual list
104105 String pkgList = props.getProperty(name + ".pkglist");
105 String[] packages = pkgList.split(",");
106 for (int i = 0; i < packages.length; i++) {
107 String pkg = packages[i].trim();
108 if (pkg.length() != 0) {
106 for (String pkg : splitToArray(pkgList)) {
107 if (!pkg.isEmpty()) {
109108 profile.pkgNames.add(pkg);
110109 }
111110 }
114113
115114 String aliasList = props.getProperty(name + ".aliases");
116115 if (aliasList != null) {
117 String[] aliases = aliasList.split(",");
118 for (int i = 0; i < aliases.length; i++) {
119 String alias = aliases[i].trim();
120 if (alias.length() != 0) {
116 for (String alias : splitToArray(aliasList)) {
117 if (!alias.isEmpty()) {
121118 ExecutionEnvironmentProfile profileAlias = new ExecutionEnvironmentProfile(
122119 alias);
123120 profileAlias.pkgNames = profile.pkgNames;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323
2424 public class ExportPackage extends BundleCapability {
2525
26 private final Set<String> uses = new HashSet<String>();
26 private final Set<String> uses = new HashSet<>();
2727
2828 public ExportPackage(String name, Version version) {
2929 super(BundleInfo.PACKAGE_TYPE, name, version);
5656 return false;
5757 }
5858 ExportPackage other = (ExportPackage) obj;
59 if (uses == null) {
60 if (other.uses != null) {
61 return false;
62 }
63 } else if (!uses.equals(other.uses)) {
64 return false;
65 }
66 return true;
59 return uses == null ? other.uses == null : uses.equals(other.uses);
6760 }
6861
69 }
62 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.List;
2322 import java.util.Map;
24 import java.util.Map.Entry;
2523
2624 public class ManifestHeaderElement {
27 private List<String> values = new ArrayList<String>();
25 private List<String> values = new ArrayList<>();
2826
29 private Map<String, String> attributes = new HashMap<String, String>();
27 private Map<String, String> attributes = new HashMap<>();
3028
31 private Map<String, String> directives = new HashMap<String, String>();
29 private Map<String, String> directives = new HashMap<>();
3230
3331 public List<String> getValues() {
3432 return values;
7068 if (other.directives.size() != directives.size()) {
7169 return false;
7270 }
73 for (Entry<String, String> directive : directives.entrySet()) {
71 for (Map.Entry<String, String> directive : directives.entrySet()) {
7472 if (!directive.getValue().equals(other.directives.get(directive.getKey()))) {
7573 return false;
7674 }
7876 if (other.attributes.size() != attributes.size()) {
7977 return false;
8078 }
81 for (Entry<String, String> attribute : attributes.entrySet()) {
79 for (Map.Entry<String, String> attribute : attributes.entrySet()) {
8280 if (!attribute.getValue().equals(other.attributes.get(attribute.getKey()))) {
8381 return false;
8482 }
8785 }
8886
8987 public String toString() {
90 String string = "";
91 Iterator<String> itValues = values.iterator();
92 while (itValues.hasNext()) {
93 string = string.concat(itValues.next());
94 if (itValues.hasNext()) {
95 string = string.concat(";");
88 StringBuilder sb = new StringBuilder();
89 for (String value : values) {
90 if (sb.length() > 0) {
91 sb.append(";");
9692 }
93 sb.append(value);
9794 }
98 for (Entry<String, String> directive : directives.entrySet()) {
99 string = string.concat(";");
100 string = string.concat(directive.getKey());
101 string = string.concat(":=");
102 string = string.concat(directive.getValue());
95 for (Map.Entry<String, String> directive : directives.entrySet()) {
96 sb.append(";").append(directive.getKey()).append(":=").append(directive.getValue());
10397 }
104 for (Entry<String, String> attribute : attributes.entrySet()) {
105 string = string.concat(";");
106 string = string.concat(attribute.getKey());
107 string = string.concat("=");
108 string = string.concat(attribute.getValue());
98 for (Map.Entry<String, String> attribute : attributes.entrySet()) {
99 sb.append(";").append(attribute.getKey()).append("=").append(attribute.getValue());
109100 }
110 return string;
101 return sb.toString();
111102 }
112103 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.text.ParseException;
2121 import java.util.ArrayList;
2222 import java.util.Collections;
23 import java.util.Iterator;
2423 import java.util.List;
2524
2625 /**
2726 * Parse a header of a manifest. The manifest header is composed with the following rules:
28 *
27 *
2928 * <pre>
3029 * header ::= header-element (',' header-element)*
3130 * header-element ::= values (';' (attribute | directive) )*
3938 */
4039 public class ManifestHeaderValue {
4140
42 private List<ManifestHeaderElement> elements = new ArrayList<ManifestHeaderElement>();
41 private List<ManifestHeaderElement> elements = new ArrayList<>();
4342
4443 ManifestHeaderValue() {
4544 // just for unit testing
7069 if (elements.isEmpty()) {
7170 return Collections.emptyList();
7271 }
73 List<String> list = new ArrayList<String>();
72 List<String> list = new ArrayList<>();
7473 for (ManifestHeaderElement element : getElements()) {
7574 list.addAll(element.getValues());
7675 }
9695 /**
9796 * buffer
9897 */
99 private StringBuffer buffer = new StringBuffer();
98 private StringBuilder buffer = new StringBuilder();
10099
101100 /**
102101 * position in the source
130129
131130 /**
132131 * Default constructor
133 *
132 *
134133 * @param header
135134 * the header to parse
136135 */
141140
142141 /**
143142 * Do the parsing
144 *
145 * @throws ParseException
143 *
144 * @throws ParseException if something goes wrong
146145 */
147146 void parse() throws ParseException {
148147 do {
264263 switch (readNext()) {
265264 case '\0':
266265 break;
267
268266 case ',':
269267 case ';':
270268 endParameterValue();
393391 }
394392
395393 public String toString() {
396 String string = "";
397 Iterator<ManifestHeaderElement> it = elements.iterator();
398 while (it.hasNext()) {
399 string = string.concat(it.next().toString());
400 if (it.hasNext()) {
401 string = string.concat(",");
402 }
403 }
404 return string;
394 StringBuilder sb = new StringBuilder();
395 for (ManifestHeaderElement element : elements) {
396 if (sb.length() > 0) {
397 sb.append(",");
398 }
399 sb.append(element.toString());
400 }
401 return sb.toString();
405402 }
406403
407404 public static void writeParseException(PrintStream out, String source, ParseException e) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.FileInputStream;
2222 import java.io.IOException;
2323 import java.io.InputStream;
24 import java.nio.charset.StandardCharsets;
2425 import java.text.ParseException;
2526 import java.util.List;
2627 import java.util.jar.Attributes;
3031 import org.apache.ivy.osgi.util.Version;
3132 import org.apache.ivy.osgi.util.VersionRange;
3233
34 import static org.apache.ivy.util.StringUtils.splitToArray;
35
3336 /**
3437 * Provides an OSGi manifest parser.
35 *
38 *
3639 */
3740 public class ManifestParser {
3841
4851
4952 private static final String BUNDLE_VERSION = "Bundle-Version";
5053
54 @SuppressWarnings("unused")
5155 private static final String BUNDLE_NAME = "Bundle-Name";
5256
5357 private static final String BUNDLE_DESCRIPTION = "Bundle-Description";
5458
5559 private static final String BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
5660
61 @SuppressWarnings("unused")
5762 private static final String BUNDLE_MANIFEST_VERSION = "Bundle-ManifestVersion";
5863
5964 private static final String BUNDLE_REQUIRED_EXECUTION_ENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
7479 ParseException {
7580 JarInputStream jis = new JarInputStream(jarStream);
7681 Manifest manifest = jis.getManifest();
82 jis.close();
7783 if (manifest == null) {
7884 return null;
7985 }
80 BundleInfo bundleInfo = parseManifest(manifest);
81 return bundleInfo;
86 return parseManifest(manifest);
8287 }
8388
8489 public static BundleInfo parseManifest(File manifestFile) throws IOException, ParseException {
85 FileInputStream fis = new FileInputStream(manifestFile);
86 try {
87 BundleInfo parseManifest = parseManifest(fis);
88 return parseManifest;
89 } finally {
90 try {
91 fis.close();
92 } catch (IOException e) {
93 // ignore
94 }
90 try (FileInputStream fis = new FileInputStream(manifestFile)) {
91 return parseManifest(fis);
9592 }
9693 }
9794
9895 public static BundleInfo parseManifest(String manifest) throws IOException, ParseException {
99 ByteArrayInputStream bais = new ByteArrayInputStream(manifest.getBytes("UTF-8"));
96 ByteArrayInputStream bais = new ByteArrayInputStream(manifest.getBytes(StandardCharsets.UTF_8));
10097 BundleInfo parseManifest = parseManifest(bais);
10198 bais.close();
10299 return parseManifest;
104101
105102 public static BundleInfo parseManifest(InputStream manifestStream) throws IOException,
106103 ParseException {
107 BundleInfo parseManifest = parseManifest(new Manifest(manifestStream));
108 return parseManifest;
104 return parseManifest(new Manifest(manifestStream));
109105 }
110106
111107 public static BundleInfo parseManifest(Manifest manifest) throws ParseException {
172168 ExportPackage export = new ExportPackage(name, v);
173169 String uses = exportElement.getDirectives().get(ATTR_USE);
174170 if (uses != null) {
175 String[] split = uses.trim().split(",");
176 for (int i = 0; i < split.length; i++) {
177 export.addUse(split[i].trim());
171 for (String use : splitToArray(uses)) {
172 export.addUse(use);
178173 }
179174 }
180175 bundleInfo.addCapability(export);
183178
184179 parseCapability(bundleInfo, mainAttributes, EXPORT_SERVICE, BundleInfo.SERVICE_TYPE);
185180
186 // handle Eclipse specific source attachement
181 // handle Eclipse specific source attachment
187182 String eclipseSourceBundle = mainAttributes.getValue(ECLIPSE_SOURCE_BUNDLE);
188183 if (eclipseSourceBundle != null) {
189184 bundleInfo.setSource(true);
257252 return new VersionRange(v);
258253 }
259254
260 private static Version versionOf(String v) throws ParseException {
255 private static Version versionOf(String v) {
261256 if (v == null) {
262257 return null;
263258 }
267262 /**
268263 * Ensure that the lines are not longer than 72 characters, so it can be parsed by the
269264 * {@link Manifest} class
270 *
271 * @param manifest
272 * @return
265 *
266 * @param manifest ditto
267 * @return String
273268 */
274269 public static String formatLines(String manifest) {
275 StringBuffer buffer = new StringBuffer(manifest.length());
276 String[] lines = manifest.split("\n");
277 for (int i = 0; i < lines.length; i++) {
278 if (lines[i].length() <= 72) {
279 buffer.append(lines[i]);
270 StringBuilder buffer = new StringBuilder(manifest.length());
271 for (String line : manifest.split("\n")) {
272 if (line.length() <= 72) {
273 buffer.append(line);
280274 buffer.append('\n');
281275 } else {
282 buffer.append(lines[i].substring(0, 72));
276 buffer.append(line, 0, 72);
283277 buffer.append("\n ");
284278 int n = 72;
285 while (n <= lines[i].length() - 1) {
279 while (n <= line.length() - 1) {
286280 int end = n + 71;
287 if (end > lines[i].length()) {
288 end = lines[i].length();
281 if (end > line.length()) {
282 end = line.length();
289283 }
290 buffer.append(lines[i].substring(n, end));
284 buffer.append(line, n, end);
291285 buffer.append('\n');
292 if (end != lines[i].length()) {
286 if (end != line.length()) {
293287 buffer.append(' ');
294288 }
295289 n = end;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.io.IOException;
2121 import java.io.InputStream;
22 import java.net.URI;
2322 import java.net.URISyntaxException;
2423 import java.net.URL;
2524 import java.text.ParseException;
3736 import org.apache.ivy.plugins.repository.Resource;
3837 import org.apache.ivy.plugins.repository.url.URLResource;
3938
39 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
40
4041 public class OSGiManifestParser implements ModuleDescriptorParser {
4142
4243 private static final OSGiManifestParser INSTANCE = new OSGiManifestParser();
5354 }
5455
5556 public boolean accept(Resource res) {
56 if (res == null || res.getName() == null || res.getName().trim().equals("")) {
57 return false;
58 }
59 return res.getName().toUpperCase(Locale.US).endsWith("MANIFEST.MF");
57 return !(res == null || isNullOrEmpty(res.getName()))
58 && res.getName().toUpperCase(Locale.US).endsWith("MANIFEST.MF");
6059 }
6160
6261 public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
6362 Resource res, boolean validate) throws ParseException, IOException {
64 Manifest m = new Manifest(res.openStream());
65 BundleInfo bundleInfo = ManifestParser.parseManifest(m);
63 final Manifest manifest;
64 try (InputStream resourceStream = res.openStream()) {
65 manifest = new Manifest(resourceStream);
66 }
67 BundleInfo bundleInfo = ManifestParser.parseManifest(manifest);
6668 try {
67 bundleInfo.addArtifact(new BundleArtifact(false, new URI(res.getName()), null));
69 bundleInfo.addArtifact(new BundleArtifact(false, descriptorURL.toURI(), null));
6870 } catch (URISyntaxException e) {
6971 throw new RuntimeException("Unsupported repository, resources names are not uris", e);
7072 }
71 return BundleInfoAdapter.toModuleDescriptor(this, null, bundleInfo, m, profileProvider);
73 return BundleInfoAdapter.toModuleDescriptor(this, null, bundleInfo, manifest, profileProvider);
7274 }
7375
7476 public void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md)
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.util.Comparator;
2121
2222 import org.apache.ivy.core.IvyContext;
23 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
24 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
2325 import org.apache.ivy.core.module.id.ModuleRevisionId;
26 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
2427 import org.apache.ivy.osgi.util.Version;
2528 import org.apache.ivy.plugins.latest.ArtifactInfo;
2629 import org.apache.ivy.plugins.latest.ComparatorLatestStrategy;
30 import org.apache.ivy.plugins.resolver.util.MDResolvedResource;
2731 import org.apache.ivy.plugins.version.VersionMatcher;
2832
2933 public class OsgiLatestStrategy extends ComparatorLatestStrategy {
3135 final class MridComparator implements Comparator<ModuleRevisionId> {
3236
3337 public int compare(ModuleRevisionId o1, ModuleRevisionId o2) {
34 Version v1;
35 Version v2;
36 try {
37 v1 = new Version(o1.getRevision());
38 v2 = new Version(o2.getRevision());
39 } catch (ParseException e) {
40 throw new RuntimeException("Uncomparable versions:" + o1.getRevision() + " and "
41 + o2.getRevision() + " (" + e.getMessage() + ")");
42 }
38 Version v1 = new Version(o1.getRevision());
39 Version v2 = new Version(o2.getRevision());
4340 try {
4441 return v1.compareTo(v2);
4542 } catch (RuntimeException e) {
7976 return c >= 0 ? -1 : 1;
8077 }
8178
82 return mridComparator.compare(mrid1, mrid2);
79 int res = mridComparator.compare(mrid1, mrid2);
80
81 if (res == 0) {
82 // if same requirements, maybe we can make a difference on the implementation ?
83 ModuleRevisionId implMrid1 = getImplMrid(o1);
84 ModuleRevisionId implMrid2 = getImplMrid(o2);
85 if (implMrid1 != null && implMrid2 != null) {
86 if (implMrid1.getModuleId().equals(implMrid2.getModuleId())) {
87 // same implementation, compare the versions
88 res = mridComparator.compare(implMrid1, implMrid2);
89 } else {
90 // not same bundle
91 // to keep a total order, compare module names even if it means nothing
92 res = implMrid1.getModuleId().compareTo(implMrid2.getModuleId());
93 }
94 }
95
96 }
97
98 return res;
99 }
100
101 /*
102 * In the resolve process, a resolved requirement is represented in a special way. Here we
103 * deconstruct the resolved resource to know which implementation is actually resolved. See
104 * AbstractOSGiResolver.buildResolvedCapabilityMd()
105 */
106 private ModuleRevisionId getImplMrid(ArtifactInfo o) {
107 if (!(o instanceof MDResolvedResource)) {
108 return null;
109 }
110 MDResolvedResource mdrr = (MDResolvedResource) o;
111 ResolvedModuleRevision rmr = mdrr.getResolvedModuleRevision();
112 if (rmr == null) {
113 return null;
114 }
115 ModuleDescriptor md = rmr.getDescriptor();
116 if (md == null) {
117 return null;
118 }
119 if (!md.getModuleRevisionId().getOrganisation().equals(BundleInfo.PACKAGE_TYPE)) {
120 return null;
121 }
122 DependencyDescriptor[] dds = md.getDependencies();
123 if (dds == null || dds.length != 1) {
124 return null;
125 }
126 return dds[0].getDependencyRevisionId();
83127 }
84128 }
85129
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * http://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
1818
1919 OSGi/Minimum-1.0.aliases = OSGI_MINIMUM-1.0
20 OSGi/Minimum-1.0.pkglist =
20 OSGi/Minimum-1.0.pkglist =
2121
2222 OSGi/Minimum-1.1.aliases = OSGI_MINIMUM-1.1
23 OSGi/Minimum-1.1.pkglist =
23 OSGi/Minimum-1.1.pkglist =
2424
2525 OSGi/Minimum-1.2.aliases = OSGI_MINIMUM-1.2
26 OSGi/Minimum-1.2.pkglist =
27
28 CDC-1.0/Foundation-1.0.aliases = CDC-1.0_Foundation-1.0
26 OSGi/Minimum-1.2.pkglist =
27
28 CDC-1.0/Foundation-1.0.aliases = CDC-1.0_Foundation-1.0
2929 CDC-1.0/Foundation-1.0.pkglist = \
3030 javax.microedition.io
3131
214214 JavaSE-1.7.extends = JavaSE-1.6
215215 JavaSE-1.7.pkglist = \
216216 javax.swing.plaf.nimbus
217
217
218218 JavaSE-1.8.extends = JavaSE-1.7
219219 JavaSE-1.8.pkglist =
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 super(filters);
2929 }
3030
31 @Override
3132 protected char operator() {
3233 return '&';
3334 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020
2121 public class CompareFilter extends OSGiFilter {
2222
23 public static enum Operator {
23 public enum Operator {
2424
2525 EQUALS("="), LOWER_THAN("<"), LOWER_OR_EQUAL("<="), GREATER_THAN(">"), GREATER_OR_EQUAL(
26 ">=");
26 ">="), APPROX("~="), PRESENT("=*");
2727
2828 private String op;
2929
30 private Operator(String op) {
30 Operator(String op) {
3131 this.op = op;
3232 }
3333
34 @Override
3435 public String toString() {
3536 return op;
3637 }
4243
4344 private final String leftValue;
4445
46 private boolean substring;
47
4548 public CompareFilter(String leftValue, Operator operator, String rightValue) {
4649 this.leftValue = leftValue;
4750 this.rightValue = rightValue;
4851 this.operator = operator;
52 this.substring = operator == Operator.EQUALS && rightValue.contains("*");
4953 }
5054
5155 public String getLeftValue() {
6064 return rightValue;
6165 }
6266
67 @Override
6368 public void append(StringBuffer builder) {
6469 builder.append("(");
6570 builder.append(leftValue);
7277 public boolean eval(Map<String, String> properties) {
7378 String actualValue = properties.get(leftValue);
7479 if (actualValue == null) {
80 return false;
81 }
82 if (operator == Operator.PRESENT) {
83 return true;
84 }
85 if (operator == Operator.APPROX) {
86 // TODO
87 return false;
88 }
89 if (substring) {
90 // TODO
7591 return false;
7692 }
7793 int diff = rightValue.compareTo(actualValue);
91107 }
92108 }
93109
110 @Override
94111 public int hashCode() {
95112 final int prime = 31;
96113 int result = 1;
100117 return result;
101118 }
102119
120 @Override
103121 public boolean equals(Object obj) {
104122 if (this == obj) {
105123 return true;
125143 } else if (!operator.equals(other.operator)) {
126144 return false;
127145 }
128 if (rightValue == null) {
129 if (other.rightValue != null) {
130 return false;
131 }
132 } else if (!rightValue.equals(other.rightValue)) {
133 return false;
134 }
135 return true;
146 return rightValue == null ? other.rightValue == null : rightValue.equals(other.rightValue);
136147 }
137148 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 public abstract class MultiOperatorFilter extends OSGiFilter {
2323
24 private List<OSGiFilter> subFilters = new ArrayList<OSGiFilter>();
24 private List<OSGiFilter> subFilters = new ArrayList<>();
2525
2626 public MultiOperatorFilter() {
2727 // default constructor
2828 }
2929
3030 public MultiOperatorFilter(OSGiFilter[] filters) {
31 for (int i = 0; i < filters.length; i++) {
32 OSGiFilter filter = filters[i];
31 for (OSGiFilter filter : filters) {
3332 add(filter);
3433 }
3534 }
3635
37 abstract protected char operator();
36 protected abstract char operator();
3837
38 @Override
3939 public void append(StringBuffer builder) {
4040 builder.append('(');
4141 builder.append(operator());
5353 return subFilters;
5454 }
5555
56 @Override
5657 public int hashCode() {
5758 final int prime = 31;
5859 int result = 1;
6263 return result;
6364 }
6465
66 @Override
6567 public boolean equals(Object obj) {
6668 if (this == obj) {
6769 return true;
6870 }
69 if (obj == null) {
70 return false;
71 }
72 if (!(obj instanceof MultiOperatorFilter)) {
71 if (obj == null || !(obj instanceof MultiOperatorFilter)) {
7372 return false;
7473 }
7574 MultiOperatorFilter other = (MultiOperatorFilter) obj;
76 if (subFilters == null) {
77 if (other.subFilters != null) {
78 return false;
79 }
80 } else if (other.subFilters == null) {
81 return false;
82 } else if (subFilters.size() != other.subFilters.size()) {
83 return false;
84 } else if (!subFilters.containsAll(other.subFilters)) {
85 return false;
86 }
87 return true;
75 return subFilters == null ? other.subFilters == null
76 : other.subFilters != null && subFilters.size() == other.subFilters.size()
77 && subFilters.containsAll(other.subFilters);
8878 }
8979 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 super(subFilter);
2525 }
2626
27 @Override
2728 protected char operator() {
2829 return '!';
2930 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020
2121 public abstract class OSGiFilter {
2222
23 @Override
2324 public String toString() {
2425 StringBuffer builder = new StringBuffer();
2526 append(builder);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5050
5151 /**
5252 * Default constructor
53 *
54 * @param header
53 *
54 * @param text
5555 * the header to parse
5656 */
5757 Parser(String text) {
6161
6262 /**
6363 * Do the parsing
64 *
65 * @return
66 *
67 * @throws ParseException
64 *
65 * @return OSGiFilter
66 *
67 * @throws ParseException if something goes wrong
6868 */
6969 OSGiFilter parse() throws ParseException {
7070 return parseFilter();
9191 if (c != '(') {
9292 throw new ParseException("Expecting '(' as the start of the filter", pos);
9393 }
94 OSGiFilter filter = parseFilterComp();
95 readNext();
96 if (c != ')') {
97 throw new ParseException("Expecting ')' as the end of the filter", pos);
98 }
99 return filter;
100 }
101
102 private OSGiFilter parseFilterComp() throws ParseException {
94103 OSGiFilter filter;
95104 switch (readNext()) {
96105 case '&':
104113 break;
105114 default:
106115 unread();
107 filter = parseCompare();
108 break;
109 }
110 readNext();
111 if (c != ')') {
112 throw new ParseException("Expecting ')' as the end of the filter", pos);
113 }
114 return filter;
115 }
116
117 private OSGiFilter parseCompare() throws ParseException {
116 filter = parseOperation();
117 break;
118 }
119 return filter;
120 }
121
122 private OSGiFilter parseOperation() throws ParseException {
118123 String leftValue = parseCompareValue();
119124 Operator operator = parseCompareOperator();
120125 String rightValue = parseCompareValue();
122127 }
123128
124129 private String parseCompareValue() {
125 StringBuffer builder = new StringBuffer();
130 StringBuilder builder = new StringBuilder();
126131 do {
127132 readNext();
128133 if (!isOperator(c) && c != ')' && c != '(') {
136141 }
137142
138143 private boolean isOperator(char ch) {
139 return ch == '=' || ch == '<' || ch == '>';
144 return ch == '=' || ch == '<' || ch == '>' || ch == '~';
140145 }
141146
142147 private Operator parseCompareOperator() throws ParseException {
143148 switch (readNext()) {
144149 case '=':
150 if (readNext() == '*') {
151 return Operator.PRESENT;
152 }
153 unread();
145154 return Operator.EQUALS;
146155 case '>':
147156 if (readNext() == '=') {
155164 }
156165 unread();
157166 return Operator.LOWER_THAN;
167 case '~':
168 if (readNext() == '=') {
169 return Operator.LOWER_OR_EQUAL;
170 }
171 unread();
158172 default:
159173 break;
160174 }
161 throw new ParseException("Expecting an operator: =, <, <=, > or >=", pos);
175 throw new ParseException("Expecting an operator: =, <, <=, >, >=, ~= or =*", pos);
162176 }
163177
164178 private OSGiFilter parseAnd() throws ParseException {
165179 AndFilter filter = new AndFilter();
166 parseMultiOperator(filter);
180 parseFilterList(filter);
167181 return filter;
168182 }
169183
170184 private OSGiFilter parseOr() throws ParseException {
171185 OrFilter filter = new OrFilter();
172 parseMultiOperator(filter);
173 return filter;
174 }
175
176 private void parseMultiOperator(MultiOperatorFilter filter) throws ParseException {
186 parseFilterList(filter);
187 return filter;
188 }
189
190 private void parseFilterList(MultiOperatorFilter filter) throws ParseException {
177191 do {
178192 skipWhiteSpace();
179193 readNext();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 super(filters);
2929 }
3030
31 @Override
3132 protected char operator() {
3233 return '|';
3334 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 this.subFilter = subFilter;
2525 }
2626
27 abstract protected char operator();
27 protected abstract char operator();
2828
29 @Override
2930 public void append(StringBuffer builder) {
3031 builder.append("(");
3132 builder.append(operator());
3738 return subFilter;
3839 }
3940
41 @Override
4042 public int hashCode() {
4143 final int prime = 31;
4244 int result = 1;
4446 return result;
4547 }
4648
49 @Override
4750 public boolean equals(Object obj) {
4851 if (this == obj) {
4952 return true;
5558 return false;
5659 }
5760 UniOperatorFilter other = (UniOperatorFilter) obj;
58 if (subFilter == null) {
59 if (other.subFilter != null) {
60 return false;
61 }
62 } else if (!subFilter.equals(other.subFilter)) {
63 return false;
64 }
65 return true;
61 return subFilter == null ? other.subFilter == null : subFilter.equals(other.subFilter);
6662 }
6763 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.net.URI;
2525 import java.net.URISyntaxException;
2626 import java.net.URL;
27 import java.text.ParseException;
2827
2928 import org.apache.ivy.core.cache.CacheResourceOptions;
3029 import org.apache.ivy.core.event.EventManager;
6160 this.forceMetadataUpdate = forceMetadataUpdate;
6261 }
6362
63 @Override
6464 protected void init() {
6565 if (repoXmlFile != null && repoXmlURL != null) {
6666 throw new RuntimeException("The OBR repository resolver " + getName()
8484 if (eventManager != null) {
8585 getRepository().addTransferListener(eventManager);
8686 }
87 Resource obrResource = new URLResource(url);
87 final Resource obrResource = new URLResource(url, this.getTimeoutConstraint());
8888 CacheResourceOptions options = new CacheResourceOptions();
8989 if (metadataTtl != null) {
90 options.setTtl(metadataTtl.longValue());
90 options.setTtl(metadataTtl);
9191 }
9292 if (forceMetadataUpdate != null) {
93 options.setForce(forceMetadataUpdate.booleanValue());
93 options.setForce(forceMetadataUpdate);
9494 }
9595 report = getRepositoryCacheManager().downloadRepositoryResource(obrResource, "obr",
9696 "obr", "xml", options, getRepository());
124124 }
125125 try {
126126 setRepoDescriptor(OBRXMLParser.parse(baseUri, in));
127 } catch (ParseException e) {
128 throw new RuntimeException("The OBR repository resolver " + getName()
129 + " couldn't be configured: the file " + sourceLocation
130 + " is incorrectly formed (" + e.getMessage() + ")", e);
131127 } catch (IOException e) {
132128 throw new RuntimeException("The OBR repository resolver " + getName()
133129 + " couldn't be configured: the file " + sourceLocation
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 public class Capability {
2323
24 private List<CapabilityProperty> properties = new ArrayList<CapabilityProperty>();
24 private List<CapabilityProperty> properties = new ArrayList<>();
2525
2626 private String name;
2727
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import org.apache.ivy.osgi.util.Version;
2525 import org.apache.ivy.util.Message;
2626
27 import static org.apache.ivy.util.StringUtils.splitToArray;
28
2729 public class CapabilityAdapter {
2830
2931 public static void adapt(BundleInfo bundleInfo, Capability capability) throws ParseException {
3032 String name = capability.getName();
31 if (BundleInfo.PACKAGE_TYPE.equals(name)) {
32 ExportPackage exportPackage = getExportPackage(bundleInfo, capability);
33 bundleInfo.addCapability(exportPackage);
34 } else if (BundleInfo.BUNDLE_TYPE.equals(name)) {
35 // nothing to do, already handled at the resource tag level
36 } else if (BundleInfo.SERVICE_TYPE.equals(name)) {
37 BundleCapability service = getOSGiService(bundleInfo, capability);
38 bundleInfo.addCapability(service);
39 } else {
40 Message.warn("Unsupported capability '" + name + "' on the bundle '"
41 + bundleInfo.getSymbolicName() + "'");
33 switch (name) {
34 case BundleInfo.PACKAGE_TYPE:
35 bundleInfo.addCapability(getExportPackage(bundleInfo, capability));
36 break;
37 case BundleInfo.BUNDLE_TYPE:
38 // nothing to do, already handled at the resource tag level
39 break;
40 case BundleInfo.SERVICE_TYPE:
41 bundleInfo.addCapability(getOSGiService(bundleInfo, capability));
42 break;
43 default:
44 Message.warn("Unsupported capability '" + name + "' on the bundle '"
45 + bundleInfo.getSymbolicName() + "'");
46 break;
4247 }
4348 }
4449
4954 String uses = null;
5055 for (CapabilityProperty property : capability.getProperties()) {
5156 String propName = property.getName();
52 if ("package".equals(propName)) {
53 pkgName = property.getValue();
54 } else if ("version".equals(propName)) {
55 version = new Version(property.getValue());
56 } else if ("uses".equals(propName)) {
57 uses = property.getValue();
58 } else {
59 Message.warn("Unsupported property '" + propName
60 + "' on the 'package' capability of the bundle '"
61 + bundleInfo.getSymbolicName() + "'");
57 switch (propName) {
58 case "package":
59 pkgName = property.getValue();
60 break;
61 case "uses":
62 uses = property.getValue();
63 break;
64 case "version":
65 version = new Version(property.getValue());
66 break;
67 default:
68 Message.warn("Unsupported property '" + propName
69 + "' on the 'package' capability of the bundle '"
70 + bundleInfo.getSymbolicName() + "'");
71 break;
6272 }
6373 }
6474 if (pkgName == null) {
6676 }
6777 ExportPackage exportPackage = new ExportPackage(pkgName, version);
6878 if (uses != null) {
69 String[] split = uses.trim().split(",");
70 for (int i = 0; i < split.length; i++) {
71 String u = split[i];
72 exportPackage.addUse(u.trim());
79 for (String use : splitToArray(uses)) {
80 exportPackage.addUse(use);
7381 }
7482 }
7583 return exportPackage;
8290
8391 for (CapabilityProperty property : capability.getProperties()) {
8492 String propName = property.getName();
85 if ("service".equals(propName)) {
86 name = property.getValue();
87 } else if ("version".equals(propName)) {
88 version = new Version(property.getValue());
89 } else {
90 Message.warn("Unsupported property '" + propName
91 + "' on the 'package' capability of the bundle '"
92 + bundleInfo.getSymbolicName() + "'");
93 switch (propName) {
94 case "service":
95 name = property.getValue();
96 break;
97 case "version":
98 version = new Version(property.getValue());
99 break;
100 default:
101 Message.warn("Unsupported property '" + propName
102 + "' on the 'package' capability of the bundle '"
103 + bundleInfo.getSymbolicName() + "'");
104 break;
93105 }
94106 }
95107
96108 if (name == null) {
97109 throw new ParseException("No service name for the capability", 0);
98110 }
99 BundleCapability service = new BundleCapability(BundleInfo.SERVICE_TYPE, name, version);
100 return service;
111 return new BundleCapability(BundleInfo.SERVICE_TYPE, name, version);
101112 }
102113 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4040
4141 public class OBRXMLParser {
4242
43 public static BundleRepoDescriptor parse(URI baseUri, InputStream in) throws ParseException,
44 IOException, SAXException {
43 public static BundleRepoDescriptor parse(URI baseUri, InputStream in) throws IOException,
44 SAXException {
4545 RepositoryHandler handler = new RepositoryHandler(baseUri);
4646 try {
4747 XMLHelper.parse(in, null, handler, null);
6767 super(REPOSITORY);
6868 this.baseUri = baseUri;
6969 addChild(new ResourceHandler(), new ChildElementHandler<ResourceHandler>() {
70 public void childHanlded(ResourceHandler child) {
70 @Override
71 public void childHandled(ResourceHandler child) {
7172 repo.addBundle(child.bundleInfo);
7273 }
7374 });
7475 }
7576
77 @Override
7678 protected void handleAttributes(Attributes atts) {
7779 repo = new BundleRepoDescriptor(baseUri,
7880 ExecutionEnvironmentProfileProvider.getInstance());
108110 // resource
109111
110112 addChild(new ResourceSourceHandler(), new ChildElementHandler<ResourceSourceHandler>() {
111 public void childHanlded(ResourceSourceHandler child) {
113 @Override
114 public void childHandled(ResourceSourceHandler child) {
112115 String uri = child.getBufferedChars().trim();
113116 if (!uri.endsWith(".jar")) {
114117 // the maven plugin is putting some useless source url sometimes...
128131 });
129132 addChild(new ResourceDescriptionHandler(),
130133 new ChildElementHandler<ResourceDescriptionHandler>() {
131 public void childHanlded(ResourceDescriptionHandler child) {
134 @Override
135 public void childHandled(ResourceDescriptionHandler child) {
132136 bundleInfo.setDescription(child.getBufferedChars().trim());
133137 }
134138 });
135139 addChild(new ResourceDocumentationHandler(),
136140 new ChildElementHandler<ResourceDocumentationHandler>() {
137 public void childHanlded(ResourceDocumentationHandler child) {
141 @Override
142 public void childHandled(ResourceDocumentationHandler child) {
138143 bundleInfo.setDocumentation(child.getBufferedChars().trim());
139144 }
140145 });
141146 addChild(new ResourceLicenseHandler(),
142147 new ChildElementHandler<ResourceLicenseHandler>() {
143 public void childHanlded(ResourceLicenseHandler child) {
148 @Override
149 public void childHandled(ResourceLicenseHandler child) {
144150 bundleInfo.setLicense(child.getBufferedChars().trim());
145151 }
146152 });
147153 addChild(new ResourceSizeHandler(), new ChildElementHandler<ResourceSizeHandler>() {
148 public void childHanlded(ResourceSizeHandler child) {
154 @Override
155 public void childHandled(ResourceSizeHandler child) {
149156 String size = child.getBufferedChars().trim();
150157 try {
151158 bundleInfo.setSize(Integer.valueOf(size));
157164 }
158165 });
159166 addChild(new CapabilityHandler(), new ChildElementHandler<CapabilityHandler>() {
160 public void childHanlded(CapabilityHandler child) throws SAXParseException {
167 @Override
168 public void childHandled(CapabilityHandler child) throws SAXParseException {
161169
162170 try {
163171 CapabilityAdapter.adapt(bundleInfo, child.capability);
168176 }
169177 });
170178 addChild(new RequireHandler(), new ChildElementHandler<RequireHandler>() {
171 public void childHanlded(RequireHandler child) throws SAXParseException {
179 @Override
180 public void childHandled(RequireHandler child) throws SAXParseException {
172181 try {
173182 RequirementAdapter.adapt(bundleInfo, child.requirement);
174183 } catch (UnsupportedFilterException e) {
182191 }
183192 });
184193 addChild(new ExtendHandler(), new ChildElementHandler<ExtendHandler>() {
185 public void childHanlded(ExtendHandler child) throws SAXParseException {
194 @Override
195 public void childHandled(ExtendHandler child) throws SAXParseException {
186196 // TODO handle fragment host
187197 }
188198 });
189199 }
190200
201 @Override
191202 protected void handleAttributes(Attributes atts) throws SAXException {
192203 String symbolicname = atts.getValue(SYMBOLIC_NAME);
193204 if (symbolicname == null) {
194 log(Message.MSG_ERR, "Resource with no symobilc name, skipping it.");
205 log(Message.MSG_ERR, "Resource with no symbolic name, skipping it.");
195206 skip();
196207 return;
197208 }
198209
199210 String v = getOptionalAttribute(atts, VERSION, DEFAULT_VERSION);
200 Version version;
201 try {
202 version = new Version(v);
203 } catch (ParseException e) {
204 log(Message.MSG_ERR, "Incorrect resource version: " + v + ". The resource "
205 + symbolicname + " is then ignored.");
206 skip();
207 return;
208 }
209
211 Version version = new Version(v);
210212 bundleInfo = new BundleInfo(symbolicname, version);
211213 bundleInfo.setPresentationName(atts.getValue(PRESENTATION_NAME));
212214 String uri = atts.getValue(URI);
223225 bundleInfo.setId(atts.getValue(ID));
224226 }
225227
228 @Override
226229 protected String getCurrentElementIdentifier() {
227230 return bundleInfo.getSymbolicName() + "/" + bundleInfo.getVersion();
228231 }
294297 super(CAPABILITY);
295298 addChild(new CapabilityPropertyHandler(),
296299 new ChildElementHandler<CapabilityPropertyHandler>() {
297 public void childHanlded(CapabilityPropertyHandler child) {
300 @Override
301 public void childHandled(CapabilityPropertyHandler child) {
298302 String name = child.name;
299303 String value = child.value;
300304 String type = child.type;
304308 });
305309 }
306310
311 @Override
307312 protected void handleAttributes(Attributes atts) throws SAXException {
308313 String name = getRequiredAttribute(atts, NAME);
309314 capability = new Capability(name);
331336 super(CAPABILITY_PROPERTY);
332337 }
333338
339 @Override
334340 protected void handleAttributes(Attributes atts) throws SAXException {
335341 name = getRequiredAttribute(atts, NAME);
336342 value = getRequiredAttribute(atts, VALUE);
356362 super(name);
357363 }
358364
365 @Override
359366 protected void handleAttributes(Attributes atts) throws SAXException {
360367 String name = getRequiredAttribute(atts, NAME);
361368
365372 try {
366373 filter = OSGiFilterParser.parse(filterText);
367374 } catch (ParseException e) {
368 throw new SAXParseException("Requirement with illformed filter: " + filterText,
375 throw new SAXParseException("Requirement with ill-formed filter: " + filterText,
369376 getLocator());
370377 }
371378 }
375382
376383 requirement = new Requirement(name, filter);
377384 if (optional != null) {
378 requirement.setOptional(optional.booleanValue());
385 requirement.setOptional(optional);
379386 }
380387 if (multiple != null) {
381 requirement.setMultiple(multiple.booleanValue());
388 requirement.setMultiple(multiple);
382389 }
383390 }
384391
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
147147 String type = capability.getType();
148148 addAttr(atts, CapabilityHandler.NAME, type);
149149 handler.startElement("", CapabilityHandler.CAPABILITY, CapabilityHandler.CAPABILITY, atts);
150 if (type.equals(BundleInfo.BUNDLE_TYPE)) {
151 // nothing to do, already handled with the resource tag
152 } else if (type.equals(BundleInfo.PACKAGE_TYPE)) {
153 saxCapabilityProperty("package", capability.getName(), handler);
154 Version v = capability.getRawVersion();
155 if (v != null) {
156 saxCapabilityProperty("version", v.toString(), handler);
157 }
158 Set<String> uses = ((ExportPackage) capability).getUses();
159 if (uses != null && !uses.isEmpty()) {
160 StringBuffer builder = new StringBuffer();
161 for (String use : uses) {
162 if (builder.length() != 0) {
163 builder.append(',');
150 switch (type) {
151 case BundleInfo.BUNDLE_TYPE:
152 // nothing to do, already handled with the resource tag
153 break;
154 case BundleInfo.PACKAGE_TYPE: {
155 saxCapabilityProperty("package", capability.getName(), handler);
156 Version v = capability.getRawVersion();
157 if (v != null) {
158 saxCapabilityProperty("version", v.toString(), handler);
159 }
160 Set<String> uses = ((ExportPackage) capability).getUses();
161 if (uses != null && !uses.isEmpty()) {
162 StringBuilder builder = new StringBuilder();
163 for (String use : uses) {
164 if (builder.length() != 0) {
165 builder.append(',');
166 }
167 builder.append(use);
164168 }
165 builder.append(use);
166 }
167 saxCapabilityProperty("uses", builder.toString(), handler);
168 }
169 } else if (type.equals(BundleInfo.SERVICE_TYPE)) {
170 saxCapabilityProperty("service", capability.getName(), handler);
171 Version v = capability.getRawVersion();
172 if (v != null) {
173 saxCapabilityProperty("version", v.toString(), handler);
174 }
175 } else {
176 // oups
169 saxCapabilityProperty("uses", builder.toString(), handler);
170 }
171 break;
172 }
173 case BundleInfo.SERVICE_TYPE: {
174 saxCapabilityProperty("service", capability.getName(), handler);
175 Version v = capability.getRawVersion();
176 if (v != null) {
177 saxCapabilityProperty("version", v.toString(), handler);
178 }
179 break;
180 }
181 default:
182 // oups
183 break;
177184 }
178185 handler.endElement("", CapabilityHandler.CAPABILITY, CapabilityHandler.CAPABILITY);
179186 handler.characters("\n".toCharArray(), 0, 1);
213220 }
214221
215222 private static String buildFilter(BundleRequirement requirement) {
216 StringBuffer filter = new StringBuffer();
223 StringBuilder filter = new StringBuilder();
217224 VersionRange v = requirement.getVersion();
218225 if (v != null) {
219226 appendVersion(filter, v);
229236 return filter.toString();
230237 }
231238
232 private static void appendVersion(StringBuffer filter, VersionRange v) {
239 private static void appendVersion(StringBuilder filter, VersionRange v) {
233240 filter.append("(&");
234241 Version start = v.getStartVersion();
235242 if (start != null) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4949 adapter.adapt(info, requirement.isOptional());
5050 }
5151
52 private void extractFilter(OSGiFilter filter) throws UnsupportedFilterException, ParseException {
52 private void extractFilter(OSGiFilter filter) throws UnsupportedFilterException {
5353 if (filter instanceof AndFilter) {
5454 AndFilter andFilter = (AndFilter) filter;
5555 for (OSGiFilter subFilter : andFilter.getSubFilters()) {
9292 }
9393
9494 private void parseCompareFilter(CompareFilter compareFilter, boolean not)
95 throws UnsupportedFilterException, ParseException {
95 throws UnsupportedFilterException {
9696 String att = compareFilter.getLeftValue();
97 if (BundleInfo.PACKAGE_TYPE.equals(att) || BundleInfo.BUNDLE_TYPE.equals(att)
98 || BundleInfo.EXECUTION_ENVIRONMENT_TYPE.equals(att) || "symbolicname".equals(att)
99 || BundleInfo.SERVICE_TYPE.equals(att)) {
100 if (not) {
101 throw new UnsupportedFilterException(
102 "Not filter on requirement comparaison is not supported");
103 }
104 if (type != null) {
105 throw new UnsupportedFilterException("Multiple requirement type are not supported");
106 }
107 if ("symbolicname".equals(att)) {
108 type = BundleInfo.BUNDLE_TYPE;
109 } else {
97 if ("symbolicname".equals(att)) {
98 att = BundleInfo.BUNDLE_TYPE;
99 }
100 switch (att) {
101 case BundleInfo.BUNDLE_TYPE:
102 case BundleInfo.EXECUTION_ENVIRONMENT_TYPE:
103 case BundleInfo.PACKAGE_TYPE:
104 case BundleInfo.SERVICE_TYPE:
105 if (not) {
106 throw new UnsupportedFilterException(
107 "Not filter on requirement comparison is not supported");
108 }
109 if (compareFilter.getOperator() != Operator.EQUALS) {
110 throw new UnsupportedFilterException(
111 "Filtering is only supported with the operator '='");
112 }
113 if (type != null) {
114 throw new UnsupportedFilterException(
115 "Multiple requirement type are not supported");
116 }
110117 type = att;
111 }
112 if (compareFilter.getOperator() != Operator.EQUALS) {
113 throw new UnsupportedFilterException(
114 "Filtering is only supported with the operator '='");
115 }
116 name = compareFilter.getRightValue();
117 } else if ("version".equals(att)) {
118 String v = compareFilter.getRightValue();
119 Version version;
120 try {
121 version = new Version(v);
122 } catch (ParseException e) {
123 throw new ParseException("Ill formed version: " + v, 0);
124 }
125 Operator operator = compareFilter.getOperator();
126 if (not) {
127 if (operator == Operator.EQUALS) {
128 throw new UnsupportedFilterException(
129 "Not filter on equals comparaison is not supported");
130 } else if (operator == Operator.GREATER_OR_EQUAL) {
131 operator = Operator.LOWER_THAN;
132 } else if (operator == Operator.GREATER_THAN) {
133 operator = Operator.LOWER_OR_EQUAL;
134 } else if (operator == Operator.LOWER_OR_EQUAL) {
135 operator = Operator.GREATER_THAN;
136 } else if (operator == Operator.LOWER_THAN) {
137 operator = Operator.GREATER_OR_EQUAL;
118 name = compareFilter.getRightValue();
119 break;
120 case "version":
121 Version version = new Version(compareFilter.getRightValue());
122 Operator operator = compareFilter.getOperator();
123 if (not) {
124 switch (operator) {
125 case EQUALS:
126 throw new UnsupportedFilterException(
127 "Not filter on equals comparison is not supported");
128 case GREATER_OR_EQUAL:
129 operator = Operator.LOWER_THAN;
130 break;
131 case GREATER_THAN:
132 operator = Operator.LOWER_OR_EQUAL;
133 break;
134 case LOWER_OR_EQUAL:
135 operator = Operator.GREATER_THAN;
136 break;
137 case LOWER_THAN:
138 operator = Operator.GREATER_OR_EQUAL;
139 break;
140 }
138141 }
139 }
140 if (operator == Operator.EQUALS) {
141 if (startVersion != null || endVersion != null) {
142 throw new UnsupportedFilterException(
143 "Multiple version matching is not supported");
142 switch (operator) {
143 case EQUALS:
144 if (startVersion != null || endVersion != null) {
145 throw new UnsupportedFilterException(
146 "Multiple version matching is not supported");
147 }
148 startVersion = version;
149 startExclusive = false;
150 endVersion = version;
151 endExclusive = false;
152 break;
153 case GREATER_OR_EQUAL:
154 if (startVersion != null) {
155 throw new UnsupportedFilterException(
156 "Multiple version matching is not supported");
157 }
158 startVersion = version;
159 startExclusive = false;
160 break;
161 case GREATER_THAN:
162 if (startVersion != null) {
163 throw new UnsupportedFilterException(
164 "Multiple version matching is not supported");
165 }
166 startVersion = version;
167 startExclusive = true;
168 break;
169 case LOWER_OR_EQUAL:
170 if (endVersion != null) {
171 throw new UnsupportedFilterException(
172 "Multiple version matching is not supported");
173 }
174 endVersion = version;
175 endExclusive = false;
176 break;
177 case LOWER_THAN:
178 if (endVersion != null) {
179 throw new UnsupportedFilterException(
180 "Multiple version matching is not supported");
181 }
182 endVersion = version;
183 endExclusive = true;
184 break;
144185 }
145 startVersion = version;
146 startExclusive = false;
147 endVersion = version;
148 endExclusive = false;
149 } else if (operator == Operator.GREATER_OR_EQUAL) {
150 if (startVersion != null) {
151 throw new UnsupportedFilterException(
152 "Multiple version matching is not supported");
153 }
154 startVersion = version;
155 startExclusive = false;
156 } else if (operator == Operator.GREATER_THAN) {
157 if (startVersion != null) {
158 throw new UnsupportedFilterException(
159 "Multiple version matching is not supported");
160 }
161 startVersion = version;
162 startExclusive = true;
163 } else if (operator == Operator.LOWER_OR_EQUAL) {
164 if (endVersion != null) {
165 throw new UnsupportedFilterException(
166 "Multiple version matching is not supported");
167 }
168 endVersion = version;
169 endExclusive = false;
170 } else if (operator == Operator.LOWER_THAN) {
171 if (endVersion != null) {
172 throw new UnsupportedFilterException(
173 "Multiple version matching is not supported");
174 }
175 endVersion = version;
176 endExclusive = true;
177 }
178 } else {
179 throw new UnsupportedFilterException("Unsupported attribute: " + att);
186 break;
187 default:
188 throw new UnsupportedFilterException("Unsupported attribute: " + att);
180189 }
181190
182191 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.osgi.obr.xml;
1818
19 @SuppressWarnings("serial")
1920 public class UnsupportedFilterException extends Exception {
2021
2122 public UnsupportedFilterException(String message) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import java.util.HashMap;
2727 import java.util.LinkedHashMap;
2828 import java.util.Map;
29 import java.util.Map.Entry;
3029
3130 import javax.xml.parsers.ParserConfigurationException;
3231
5150 this.repoUrl = repoUrl;
5251 }
5352
54 public void parse(InputStream in) throws ParseException, IOException, SAXException {
53 public void parse(InputStream in) throws IOException, ParseException, SAXException {
5554 RepositoryHandler handler = new RepositoryHandler(p2Descriptor, repoUrl);
5655 try {
5756 XMLHelper.parse(in, null, handler, null);
7069 //
7170 // private static final String VERSION = "version";
7271
73 private Map<OSGiFilter, String> artifactPatterns = new LinkedHashMap<OSGiFilter, String>();
72 private Map<OSGiFilter, String> artifactPatterns = new LinkedHashMap<>();
7473
7574 public RepositoryHandler(final P2Descriptor p2Descriptor, String repoUrl) {
7675 super(REPOSITORY);
7776 // addChild(new PropertiesHandler(), new ChildElementHandler<PropertiesHandler>() {
78 // public void childHanlded(PropertiesHandler child) {
77 // public void childHandled(PropertiesHandler child) {
7978 // }
8079 // });
8180 addChild(new MappingsHandler(), new ChildElementHandler<MappingsHandler>() {
82 public void childHanlded(MappingsHandler child) {
83 for (Entry<String, String> entry : child.outputByFilter.entrySet()) {
81 @Override
82 public void childHandled(MappingsHandler child) {
83 for (Map.Entry<String, String> entry : child.outputByFilter.entrySet()) {
8484 OSGiFilter filter;
8585 try {
8686 filter = OSGiFilterParser.parse(entry.getKey());
9494 });
9595 addChild(new ArtifactsHandler(p2Descriptor, artifactPatterns, repoUrl),
9696 new ChildElementHandler<ArtifactsHandler>() {
97 public void childHanlded(ArtifactsHandler child) {
97 @Override
98 public void childHandled(ArtifactsHandler child) {
9899 // nothing to do
99100 }
100101 });
117118 public MappingsHandler() {
118119 super(MAPPINGS);
119120 addChild(new RuleHandler(), new ChildElementHandler<RuleHandler>() {
120 public void childHanlded(RuleHandler child) {
121 @Override
122 public void childHandled(RuleHandler child) {
121123 outputByFilter.put(child.filter, child.output);
122124 }
123125 });
124126 }
125127
128 @Override
126129 protected void handleAttributes(Attributes atts) {
127130 int size = Integer.parseInt(atts.getValue(SIZE));
128 outputByFilter = new LinkedHashMap<String, String>(size);
131 outputByFilter = new LinkedHashMap<>(size);
129132 }
130133
131134 }
146149 super(RULE);
147150 }
148151
152 @Override
149153 protected void handleAttributes(Attributes atts) {
150154 filter = atts.getValue(FILTER);
151155 output = atts.getValue(OUTPUT);
163167 final Map<OSGiFilter, String> artifactPatterns, final String repoUrl) {
164168 super(ARTIFACTS);
165169 addChild(new ArtifactHandler(), new ChildElementHandler<ArtifactHandler>() {
166 public void childHanlded(ArtifactHandler child) throws SAXParseException {
170 @Override
171 public void childHandled(ArtifactHandler child) throws SAXParseException {
167172 String url = getPattern(child.p2Artifact, child.properties);
168173 if (url != null) {
169174 url = url.replaceAll("\\$\\{repoUrl\\}", repoUrl);
173178 URI uri;
174179 try {
175180 uri = new URL(url).toURI();
176 } catch (MalformedURLException e) {
177 throw new SAXParseException("Incorrect artifact url '" + url + "' ("
178 + e.getMessage() + ")", getLocator(), e);
179 } catch (URISyntaxException e) {
181 } catch (MalformedURLException | URISyntaxException e) {
180182 throw new SAXParseException("Incorrect artifact url '" + url + "' ("
181183 + e.getMessage() + ")", getLocator(), e);
182184 }
187189 }
188190
189191 private String getPattern(P2Artifact p2Artifact, Map<String, String> properties) {
190 Map<String, String> props = new HashMap<String, String>(properties);
192 Map<String, String> props = new HashMap<>(properties);
191193 props.put("classifier", p2Artifact.getClassifier());
192 for (Entry<OSGiFilter, String> pattern : artifactPatterns.entrySet()) {
194 for (Map.Entry<OSGiFilter, String> pattern : artifactPatterns.entrySet()) {
193195 if (pattern.getKey().eval(props)) {
194196 return pattern.getValue();
195197 }
223225 public ArtifactHandler() {
224226 super(ARTIFACT);
225227 addChild(new PropertiesHandler(), new ChildElementHandler<PropertiesHandler>() {
226 public void childHanlded(PropertiesHandler child) {
228 @Override
229 public void childHandled(PropertiesHandler child) {
227230 properties = child.properties;
228231 }
229232 });
230233 }
231234
235 @Override
232236 protected void handleAttributes(Attributes atts) throws SAXException {
233237 String id = atts.getValue(ID);
234 Version version;
235 try {
236 version = new Version(atts.getValue(VERSION));
237 } catch (ParseException e) {
238 throw new SAXException("Incorrect version attribute on artifact '" + id + "': "
239 + atts.getValue(VERSION) + " (" + e.getMessage() + ")");
240 }
238 Version version = new Version(atts.getValue(VERSION));
241239 String classifier = atts.getValue(CLASSIFIER);
242240
243241 p2Artifact = new P2Artifact(id, version, classifier);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3434
3535 public class P2CompositeParser implements XMLInputParser {
3636
37 private Set<String> childLocations = new LinkedHashSet<String>();
37 private Set<String> childLocations = new LinkedHashSet<>();
3838
3939 public Set<String> getChildLocations() {
4040 return childLocations;
4141 }
4242
43 public void parse(InputStream in) throws ParseException, IOException, SAXException {
43 public void parse(InputStream in) throws IOException, ParseException, SAXException {
4444 RepositoryHandler handler = new RepositoryHandler();
4545 try {
4646 XMLHelper.parse(in, null, handler, null);
6565 public RepositoryHandler() {
6666 super(REPOSITORY);
6767 addChild(new ChildrenHandler(), new ChildElementHandler<ChildrenHandler>() {
68 public void childHanlded(ChildrenHandler child) {
68 @Override
69 public void childHandled(ChildrenHandler child) {
6970 childLocations = child.childLocations;
7071 }
7172 });
8889 public ChildrenHandler() {
8990 super(CHILDREN);
9091 addChild(new ChildHandler(), new ChildElementHandler<ChildHandler>() {
91 public void childHanlded(ChildHandler child) {
92 @Override
93 public void childHandled(ChildHandler child) {
9294 childLocations.add(child.location);
9395 }
9496 });
9597 }
9698
99 @Override
97100 protected void handleAttributes(Attributes atts) {
98101 int size = Integer.parseInt(atts.getValue(SIZE));
99 childLocations = new ArrayList<String>(size);
102 childLocations = new ArrayList<>(size);
100103 }
101104
102105 }
113116 super(CHILD);
114117 }
115118
119 @Override
116120 protected void handleAttributes(Attributes atts) {
117121 location = atts.getValue(LOCATION);
118122 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3131
3232 public class P2Descriptor extends EditableRepoDescriptor {
3333
34 private Map<String, Map<Version, BundleInfo>> sourceTargetBundles = new HashMap<String, Map<Version, BundleInfo>>();
34 private Map<String, Map<Version, BundleInfo>> sourceTargetBundles = new HashMap<>();
3535
36 private Map<String, Map<Version, BundleInfo>> sourceBundles = new HashMap<String, Map<Version, BundleInfo>>();
36 private Map<String, Map<Version, BundleInfo>> sourceBundles = new HashMap<>();
3737
3838 public P2Descriptor(URI repoUri, ExecutionEnvironmentProfileProvider profileProvider) {
3939 super(repoUri, profileProvider);
5050 }
5151 Map<Version, BundleInfo> byVersion = sourceBundles.get(bundleInfo.getSymbolicName());
5252 if (byVersion == null) {
53 byVersion = new HashMap<Version, BundleInfo>();
53 byVersion = new HashMap<>();
5454 sourceBundles.put(bundleInfo.getSymbolicName(), byVersion);
5555 }
5656 byVersion.put(bundleInfo.getVersion(), bundleInfo);
5858 Map<Version, BundleInfo> byTargetVersion = sourceTargetBundles.get(bundleInfo
5959 .getSymbolicNameTarget());
6060 if (byTargetVersion == null) {
61 byTargetVersion = new HashMap<Version, BundleInfo>();
61 byTargetVersion = new HashMap<>();
6262 sourceTargetBundles.put(bundleInfo.getSymbolicNameTarget(), byTargetVersion);
6363 }
6464 BundleInfo old = byTargetVersion.put(bundleInfo.getVersionTarget(), bundleInfo);
8383 return;
8484 }
8585 for (String bundleId : bundleIds) {
86 Set<ModuleDescriptorWrapper> modules = findModules(BundleInfo.BUNDLE_TYPE, bundleId);
87 for (ModuleDescriptorWrapper mdw : modules) {
86 for (ModuleDescriptorWrapper mdw : findModules(BundleInfo.BUNDLE_TYPE, bundleId)) {
8887 String symbolicName = mdw.getBundleInfo().getSymbolicName();
8988 Map<Version, BundleInfo> byVersion = sourceTargetBundles.get(symbolicName);
9089 if (byVersion == null) {
135134 }
136135 }
137136
138 BundleArtifact best = artifact;
139
140137 if (same != null) {
141138 // we have two artifacts for the same bundle, let's choose a "packed" one
142139 if (artifact.getFormat() == null || same.getFormat() != null) {
146143 bundle.removeArtifact(same);
147144 }
148145
149 bundle.addArtifact(best);
146 bundle.addArtifact(artifact);
150147 }
151148 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5555 this.logLevel = logLevel;
5656 }
5757
58 public void parse(InputStream in) throws ParseException, IOException, SAXException {
58 public void parse(InputStream in) throws IOException, ParseException, SAXException {
5959 RepositoryHandler handler = new RepositoryHandler(p2Descriptor);
6060 try {
6161 XMLHelper.parse(in, null, handler, null);
8484 super(REPOSITORY);
8585 // addChild(new PropertiesHandler(P2_TIMESTAMP),
8686 // new ChildElementHandler<PropertiesHandler>() {
87 // public void childHanlded(PropertiesHandler child) {
87 // public void childHandled(PropertiesHandler child) {
8888 // String timestamp = child.properties.get(P2_TIMESTAMP);
8989 // if (timestamp != null) {
9090 // p2Descriptor.setTimestamp(Long.parseLong(timestamp));
9292 // }
9393 // });
9494 addChild(new UnitsHandler(), new ChildElementHandler<UnitsHandler>() {
95 public void childHanlded(UnitsHandler child) {
95 @Override
96 public void childHandled(UnitsHandler child) {
9697 for (BundleInfo bundle : child.bundles) {
9798 p2Descriptor.addBundle(bundle);
9899 }
99100 }
100101 });
101102 addChild(new ReferencesHandler(), new ChildElementHandler<ReferencesHandler>() {
102 public void childHanlded(ReferencesHandler child) {
103 @Override
104 public void childHandled(ReferencesHandler child) {
103105 }
104106 });
105107 }
125127 super(REFERENCES);
126128 addChild(new RepositoryReferenceHandler(),
127129 new ChildElementHandler<RepositoryReferenceHandler>() {
128 public void childHanlded(RepositoryReferenceHandler child) {
130 @Override
131 public void childHandled(RepositoryReferenceHandler child) {
129132 repositoryUris.add(child.uri);
130133 }
131134 });
132135 }
133136
137 @Override
134138 protected void handleAttributes(Attributes atts) throws SAXException {
135139 int size = Integer.parseInt(atts.getValue(SIZE));
136 repositoryUris = new ArrayList<URI>(size);
140 repositoryUris = new ArrayList<>(size);
137141 }
138142 }
139143
163167
164168 URI uri;
165169
170 @Override
166171 protected void handleAttributes(Attributes atts) throws SAXException {
167172 // type = Integer.parseInt(atts.getValue(TYPE));
168173 // options = Integer.parseInt(atts.getValue(OPTIONS));
201206 public UnitsHandler() {
202207 super(UNITS);
203208 addChild(new UnitHandler(), new ChildElementHandler<UnitHandler>() {
204 public void childHanlded(UnitHandler child) {
209 @Override
210 public void childHandled(UnitHandler child) {
205211 if (child.bundleInfo != null && !child.bundleInfo.getCapabilities().isEmpty()) {
206212 bundles.add(child.bundleInfo);
207213 }
209215 });
210216 }
211217
218 @Override
212219 protected void handleAttributes(Attributes atts) {
213220 int size = Integer.parseInt(atts.getValue(SIZE));
214 bundles = new ArrayList<BundleInfo>(size);
221 bundles = new ArrayList<>(size);
215222 }
216223
217224 }
233240 public UnitHandler() {
234241 super(UNIT);
235242 // addChild(new UpdateHandler(), new ChildElementHandler() {
236 // public void childHanlded(DelegetingHandler child) {
243 // public void childHandled(DelegatingHandler child) {
237244 // }
238245 // });
239246 addChild(new PropertiesHandler(CATEGORY_PROPERTY),
240247 new ChildElementHandler<PropertiesHandler>() {
241 public void childHanlded(PropertiesHandler child) {
248 @Override
249 public void childHandled(PropertiesHandler child) {
242250 String category = child.properties.get(CATEGORY_PROPERTY);
243 if (category != null && Boolean.valueOf(category).booleanValue()) {
251 if (category != null && Boolean.valueOf(category)) {
244252 // this is a category definition, this is useless, skip this unit
245253 child.getParent().skip();
246254 bundleInfo = null;
248256 }
249257 });
250258 addChild(new ProvidesHandler(), new ChildElementHandler<ProvidesHandler>() {
251 public void childHanlded(ProvidesHandler child) {
259 @Override
260 public void childHandled(ProvidesHandler child) {
252261 if ("source".equals(child.eclipseType)) {
253262 // this is some source of some bundle
254263 bundleInfo.setSource(true);
255 // we need to parse the manifest in the toupointData to figure out the
264 // we need to parse the manifest in the touchpointData to figure out the
256265 // targeted bundle
257266 // in case we won't have the proper data in the manifest, prepare the source
258267 // data from the convention
269278 }
270279 });
271280 addChild(new FilterHandler(), new ChildElementHandler<FilterHandler>() {
272 public void childHanlded(FilterHandler child) {
281 @Override
282 public void childHandled(FilterHandler child) {
273283 }
274284 });
275285 addChild(new RequiresHandler(), new ChildElementHandler<RequiresHandler>() {
276 public void childHanlded(RequiresHandler child) {
286 @Override
287 public void childHandled(RequiresHandler child) {
277288 for (BundleRequirement requirement : child.requirements) {
278289 bundleInfo.addRequirement(requirement);
279290 }
281292 });
282293 addChild(new HostRequirementsHandler(),
283294 new ChildElementHandler<HostRequirementsHandler>() {
284 public void childHanlded(HostRequirementsHandler child) {
295 @Override
296 public void childHandled(HostRequirementsHandler child) {
285297 }
286298 });
287299 addChild(new MetaRequirementsHandler(),
288300 new ChildElementHandler<MetaRequirementsHandler>() {
289 public void childHanlded(MetaRequirementsHandler child) {
301 @Override
302 public void childHandled(MetaRequirementsHandler child) {
290303 }
291304 });
292305 addChild(new ArtifactsHandler(), new ChildElementHandler<ArtifactsHandler>() {
293 public void childHanlded(ArtifactsHandler child) {
306 @Override
307 public void childHandled(ArtifactsHandler child) {
294308 }
295309 });
296310 // addChild(new TouchpointHandler(), new ChildElementHandler() {
297 // public void childHanlded(DelegetingHandler child) {
311 // public void childHandled(DelegatingHandler child) {
298312 // }
299313 // });
300314 addChild(new TouchpointDataHandler(), new ChildElementHandler<TouchpointDataHandler>() {
301 public void childHanlded(TouchpointDataHandler child) throws SAXParseException {
315 @Override
316 public void childHandled(TouchpointDataHandler child) throws SAXParseException {
302317 if (child.zipped != null) {
303 bundleInfo.setHasInnerClasspath(child.zipped.booleanValue());
318 bundleInfo.setHasInnerClasspath(child.zipped);
304319 }
305320 if (!bundleInfo.isSource()) {
306321 // we only care about parsing the manifest if it is a source
360375 }
361376 });
362377 // addChild(new LicensesHandler(), new ChildElementHandler() {
363 // public void childHanlded(DelegetingHandler child) {
378 // public void childHandled(DelegatingHandler child) {
364379 // }
365380 // });
366381 // addChild(new CopyrightHandler(), new ChildElementHandler() {
367 // public void childHanlded(DelegetingHandler child) {
382 // public void childHandled(DelegatingHandler child) {
368383 // }
369384 // });
370385 // addChild(new ChangesHandler(), new ChildElementHandler() {
371 // public void childHanlded(DelegetingHandler child) {
386 // public void childHandled(DelegatingHandler child) {
372387 // }
373388 // });
374389
375390 }
376391
392 @Override
377393 protected void handleAttributes(Attributes atts) throws SAXException {
378394 String id = atts.getValue(ID);
379395 String version = atts.getValue(VERSION);
380396 // Boolean singleton = Boolean.valueOf(atts.getValue(SINGLETON));
381 try {
382 bundleInfo = new BundleInfo(id, new Version(version));
383 } catch (ParseException e) {
384 throw new SAXException("Incorrect version on bundle '" + id + "': " + version
385 + " (" + e.getMessage() + ")");
386 }
387 }
388
389 }
390
391 // static class UpdateHandler extends DelegetingHandler {
397 bundleInfo = new BundleInfo(id, new Version(version));
398 }
399
400 }
401
402 // static class UpdateHandler extends DelegatingHandler {
392403 //
393404 // private static final String UPDATE = "update";
394405 //
422433 }
423434
424435 private static String namespace2Type(String namespace) {
436 if (namespace == null) {
437 return null;
438 }
425439 if (namespace.equals("java.package")) {
426440 return BundleInfo.PACKAGE_TYPE;
427441 }
444458 public ProvidesHandler() {
445459 super(PROVIDES);
446460 addChild(new ProvidedHandler(), new ChildElementHandler<ProvidedHandler>() {
447 public void childHanlded(ProvidedHandler child) {
461 @Override
462 public void childHandled(ProvidedHandler child) {
448463 if (child.namespace.equals("org.eclipse.equinox.p2.eclipse.type")) {
449464 eclipseType = child.name;
450465 } else {
457472 return;
458473 }
459474 BundleCapability capability;
460 if (type == BundleInfo.PACKAGE_TYPE) {
475 if (BundleInfo.PACKAGE_TYPE.equals(type)) {
461476 capability = new ExportPackage(child.name, child.version);
462477 } else {
463478 capability = new BundleCapability(type, child.name, child.version);
468483 });
469484 }
470485
486 @Override
471487 protected void handleAttributes(Attributes atts) {
472488 int size = Integer.parseInt(atts.getValue(SIZE));
473 capabilities = new ArrayList<BundleCapability>(size);
489 capabilities = new ArrayList<>(size);
474490 }
475491
476492 }
495511 super(PROVIDED);
496512 }
497513
514 @Override
498515 protected void handleAttributes(Attributes atts) throws SAXException {
499516 namespace = atts.getValue(NAMESPACE);
500517 name = atts.getValue(NAME);
501 try {
502 version = new Version(atts.getValue(VERSION));
503 } catch (ParseException e) {
504 throw new SAXException("Incorrect version on provided capability: " + version
505 + " (" + e.getMessage() + ")");
506 }
518 version = new Version(atts.getValue(VERSION));
507519 }
508520
509521 }
517529 public AbstractRequirementHandler(String name) {
518530 super(name);
519531 addChild(new RequiredHandler(), new ChildElementHandler<RequiredHandler>() {
520 public void childHanlded(RequiredHandler child) {
532 @Override
533 public void childHandled(RequiredHandler child) {
521534 String name = child.name;
522535 VersionRange range = child.range;
523536 String type = namespace2Type(child.namespace);
534547 });
535548 }
536549
550 @Override
537551 protected void handleAttributes(Attributes atts) {
538552 int size = Integer.parseInt(atts.getValue(SIZE));
539 requirements = new ArrayList<BundleRequirement>(size);
553 requirements = new ArrayList<>(size);
540554 }
541555
542556 }
580594 public RequiredHandler() {
581595 super(REQUIRED);
582596 // addChild(new FilterHandler(), new ChildElementHandler<FilterHandler>() {
583 // public void childHanlded(FilterHandler child) {
597 // public void childHandled(FilterHandler child) {
584598 // filter = child.getBufferedChars().trim();
585599 // }
586600 // });
587601 }
588602
603 @Override
589604 protected void handleAttributes(Attributes atts) throws SAXParseException {
590605 namespace = atts.getValue(NAMESPACE);
591606 name = atts.getValue(NAME);
595610 throw new RuntimeException(e);
596611 }
597612 // greedy = getOptionalBooleanAttribute(atts, GREEDY, Boolean.TRUE).booleanValue();
598 optional = getOptionalBooleanAttribute(atts, OPTIONAL, Boolean.FALSE).booleanValue();
613 optional = getOptionalBooleanAttribute(atts, OPTIONAL, Boolean.FALSE);
599614 }
600615
601616 }
631646 public ArtifactsHandler() {
632647 super(ARTIFACTS);
633648 addChild(new ArtifactHandler(), new ChildElementHandler<ArtifactHandler>() {
634 public void childHanlded(ArtifactHandler child) {
649 @Override
650 public void childHandled(ArtifactHandler child) {
635651 artifacts.add(child.artifact);
636652 }
637653 });
638654 }
639655
656 @Override
640657 protected void handleAttributes(Attributes atts) {
641658 int size = Integer.parseInt(atts.getValue(SIZE));
642 artifacts = new ArrayList<P2Artifact>(size);
659 artifacts = new ArrayList<>(size);
643660 }
644661
645662 }
660677 super(ARTIFACT);
661678 }
662679
680 @Override
663681 protected void handleAttributes(Attributes atts) throws SAXException {
664682 String id = atts.getValue(ID);
665683 String version = atts.getValue(VERSION);
666684 String classifier = atts.getValue(CLASSIFIER);
667 try {
668 artifact = new P2Artifact(id, new Version(version), classifier);
669 } catch (ParseException e) {
670 throw new SAXException("Incorrect version on artifact '" + id + "': " + version
671 + " (" + e.getMessage() + ")");
672 }
673 }
674
675 }
676
677 // private static class TouchpointHandler extends DelegetingHandler {
685 artifact = new P2Artifact(id, new Version(version), classifier);
686 }
687
688 }
689
690 // private static class TouchpointHandler extends DelegatingHandler {
678691 //
679692 // private static final String TOUCHPOINT = "touchpoint";
680693 //
706719 public TouchpointDataHandler() {
707720 super(TOUCHPOINTDATA);
708721 addChild(new InstructionsHandler(), new ChildElementHandler<InstructionsHandler>() {
709 public void childHanlded(InstructionsHandler child) {
722 @Override
723 public void childHandled(InstructionsHandler child) {
710724 manifest = child.manifest;
711725 zipped = child.zipped;
712726 }
713727 });
714728 }
715729
730 @Override
716731 protected void handleAttributes(Attributes atts) {
717732 // String size = atts.getValue(SIZE);
718733 }
732747 public InstructionsHandler() {
733748 super(INSTRUCTIONS);
734749 addChild(new InstructionHandler(), new ChildElementHandler<InstructionHandler>() {
735 public void childHanlded(InstructionHandler child) {
750 @Override
751 public void childHandled(InstructionHandler child) {
736752 manifest = null;
737753 zipped = null;
738754 String buffer = child.getBufferedChars().trim();
745761 });
746762 }
747763
764 @Override
748765 protected void handleAttributes(Attributes atts) {
749766 // String size = atts.getValue(SIZE);
750767 }
764781 setBufferingChar(true);
765782 }
766783
784 @Override
767785 protected void handleAttributes(Attributes atts) {
768786 key = atts.getValue(KEY);
769787 }
770788
771789 }
772790
773 // private static class LicensesHandler extends DelegetingHandler {
791 // private static class LicensesHandler extends DelegatingHandler {
774792 //
775793 // private static final String LICENSES = "licenses";
776794 //
779797 // public LicensesHandler() {
780798 // super(LICENSES);
781799 // addChild(new LicenseHandler(), new ChildElementHandler() {
782 // public void childHanlded(DelegetingHandler child) {
800 // public void childHandled(DelegatingHandler child) {
783801 // }
784802 // });
785803 // }
790808 //
791809 // }
792810
793 // private static class LicenseHandler extends DelegetingHandler {
811 // private static class LicenseHandler extends DelegatingHandler {
794812 //
795813 // private static final String LICENSE = "license";
796814 //
810828 //
811829 // }
812830
813 // private static class CopyrightHandler extends DelegetingHandler {
831 // private static class CopyrightHandler extends DelegatingHandler {
814832 //
815833 // private static final String COPYRIGHT = "copyright";
816834 //
829847 //
830848 // }
831849
832 // private class ChangesHandler extends DelegetingHandler {
850 // private class ChangesHandler extends DelegatingHandler {
833851 //
834852 // private static final String CHANGES = "changes";
835853 //
838856 // public ChangesHandler() {
839857 // super(CHANGES);
840858 // addChild(new ChangeHandler(), new ChildElementHandler<ChangeHandler>() {
841 // public void childHanlded(ChangeHandler child) {
859 // public void childHandled(ChangeHandler child) {
842860 // }
843861 // });
844862 // }
848866 // }
849867 // }
850868
851 // private class ChangeHandler extends DelegetingHandler {
869 // private class ChangeHandler extends DelegatingHandler {
852870 //
853871 // private static final String CHANGE = "change";
854872 //
877895 //
878896 // }
879897
880 // private class PatchScopeHandler extends DelegetingHandler {
898 // private class PatchScopeHandler extends DelegatingHandler {
881899 //
882900 // private static final String PATCH_SCOPE = "patchScope";
883901 //
886904 // public PatchScopeHandler() {
887905 // super(PATCH_SCOPE);
888906 // addChild(new PatchScopeHandler(), new ChildElementHandler<PatchScopeHandler>() {
889 // public void childHanlded(PatchScopeHandler child) {
907 // public void childHandled(PatchScopeHandler child) {
890908 // }
891909 // });
892910 // }
896914 // }
897915 // }
898916
899 // private class ScopeHandler extends DelegetingHandler {
917 // private class ScopeHandler extends DelegatingHandler {
900918 //
901919 // private static final String SCOPE = "scope";
902920 //
903921 // public ScopeHandler() {
904922 // super(SCOPE);
905923 // addChild(new RequiresHandler(), new ChildElementHandler<RequiresHandler>() {
906 // public void childHanlded(RequiresHandler child) {
924 // public void childHandled(RequiresHandler child) {
907925 // }
908926 // });
909927 // }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3838 super(PROPERTIES);
3939 final List<String> propList = Arrays.asList(props);
4040 addChild(new PropertyHandler(), new ChildElementHandler<PropertyHandler>() {
41 public void childHanlded(PropertyHandler child) {
41 @Override
42 public void childHandled(PropertyHandler child) {
4243 if (propList.isEmpty() || propList.contains(child.name)) {
4344 properties.put(child.name, child.value);
4445 }
4647 });
4748 }
4849
50 @Override
4951 protected void handleAttributes(Attributes atts) {
5052 int size = Integer.parseInt(atts.getValue(SIZE));
51 properties = new HashMap<String, String>(size);
53 properties = new HashMap<>(size);
5254 }
5355
5456 }
6971 super(PROPERTY);
7072 }
7173
74 @Override
7275 protected void handleAttributes(Attributes atts) {
7376 name = atts.getValue(NAME);
7477 value = atts.getValue(VALUE);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424
2525 public interface XMLInputParser {
2626
27 public void parse(InputStream in) throws ParseException, IOException, SAXException;
27 void parse(InputStream in) throws IOException, ParseException, SAXException;
2828
2929 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4343 return new FSManifestIterator();
4444 }
4545
46 abstract protected List<T> listBundleFiles(T dir) throws IOException;
46 protected abstract List<T> listBundleFiles(T dir) throws IOException;
4747
48 abstract protected List<T> listDirs(T dir) throws IOException;
48 protected abstract List<T> listDirs(T dir) throws IOException;
4949
50 abstract protected InputStream getInputStream(T f) throws IOException;
50 protected abstract InputStream getInputStream(T f) throws IOException;
5151
52 abstract protected URI buildBundleURI(T location) throws IOException;
52 protected abstract URI buildBundleURI(T location) throws IOException;
5353
5454 class FSManifestIterator implements Iterator<ManifestAndLocation> {
5555
6161 * the stack is an iterator on the children on the root. The last iterator in the stack
6262 * points to {@link #currentDir}.
6363 */
64 private Stack<Iterator<T>> dirs = new Stack<Iterator<T>>();
64 private Stack<Iterator<T>> dirs = new Stack<>();
6565
6666 /**
6767 * The bundles files being lookup.
7171 private T currentDir = null;
7272
7373 FSManifestIterator() {
74 dirs.add(Collections.<T> singleton(root).iterator());
74 dirs.add(Collections.singleton(root).iterator());
7575 }
7676
7777 /**
100100 }
101101 } else if (bundleCandidates.hasNext()) {
102102 T bundleCandidate = bundleCandidates.next();
103 JarInputStream in = null;
104 try {
105 in = new JarInputStream(getInputStream(bundleCandidate));
103 try (JarInputStream in = new JarInputStream(getInputStream(bundleCandidate))) {
106104 Manifest manifest = in.getManifest();
107105 if (manifest != null) {
108106 next = new ManifestAndLocation(manifest,
114112 Message.debug("Jar file just removed: " + bundleCandidate, e);
115113 } catch (IOException e) {
116114 Message.warn("Unreadable jar: " + bundleCandidate, e);
117 } finally {
118 if (in != null) {
119 try {
120 in.close();
121 } catch (IOException e) {
122 // Don't care
123 }
124 }
125115 }
126116 } else {
127117 // no more candidate on the current directory
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.io.IOException;
2121 import java.net.URL;
22 import java.text.ParseException;
2322 import java.util.ArrayList;
2423 import java.util.Arrays;
2524 import java.util.Collection;
2726 import java.util.Date;
2827 import java.util.HashMap;
2928 import java.util.HashSet;
30 import java.util.Iterator;
3129 import java.util.List;
3230 import java.util.Map;
33 import java.util.Map.Entry;
3431 import java.util.Set;
3532
3633 import org.apache.ivy.core.IvyPatternHelper;
5855 import org.apache.ivy.plugins.resolver.util.ResourceMDParser;
5956 import org.apache.ivy.util.Message;
6057
58 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
59
6160 public abstract class AbstractOSGiResolver extends BasicResolver {
6261
6362 private static final String CAPABILITY_EXTRA_ATTR = "osgi_bundle";
119118 }
120119 }
121120
122 abstract protected void init();
121 protected abstract void init();
123122
124123 public RepoDescriptor getRepoDescriptor() {
125124 ensureInit();
179178
180179 public ResolvedResource[] findCapability(DependencyDescriptor dd, ResolveData data,
181180 Collection<ModuleDescriptor> mds) {
182 ResolvedResource[] ret = new ResolvedResource[mds.size()];
183 int i = 0;
181 List<ResolvedResource> ret = new ArrayList<>(mds.size());
184182 for (ModuleDescriptor md : mds) {
185183 IvyNode node = data.getNode(md.getModuleRevisionId());
186184 if (node != null && node.getDescriptor() != null) {
187185 // already resolved import, no need to go further
188186 return new ResolvedResource[] {buildResolvedCapabilityMd(dd, node.getDescriptor())};
189187 }
190 ret[i++] = buildResolvedCapabilityMd(dd, md);
191 }
192 return ret;
188 ret.add(buildResolvedCapabilityMd(dd, md));
189 }
190 return ret.toArray(new ResolvedResource[mds.size()]);
193191 }
194192
195193 private MDResolvedResource buildResolvedCapabilityMd(DependencyDescriptor dd,
243241 // several candidates with different symbolic name : make an warning about the ambiguity
244242 if (rress.length != 1) {
245243 // several candidates with different symbolic name ?
246 Map<String, List<MDResolvedResource>> matching = new HashMap<String, List<MDResolvedResource>>();
247 for (int i = 0; i < rress.length; i++) {
248 String name = ((MDResolvedResource) rress[i]).getResolvedModuleRevision()
244 Map<String, List<MDResolvedResource>> matching = new HashMap<>();
245 for (ResolvedResource rres : rress) {
246 String name = ((MDResolvedResource) rres).getResolvedModuleRevision()
249247 .getDescriptor().getExtraAttribute(CAPABILITY_EXTRA_ATTR);
250248 List<MDResolvedResource> list = matching.get(name);
251249 if (list == null) {
252 list = new ArrayList<MDResolvedResource>();
250 list = new ArrayList<>();
253251 matching.put(name, list);
254252 }
255 list.add((MDResolvedResource) rress[i]);
253 list.add((MDResolvedResource) rres);
256254 }
257255 if (matching.keySet().size() != 1) {
258256 if (requirementStrategy == RequirementStrategy.first) {
259257 Message.warn("Ambiguity for the '" + osgiType + "' requirement "
260258 + mrid.getName() + ";version=" + mrid.getRevision());
261 for (Entry<String, List<MDResolvedResource>> entry : matching.entrySet()) {
259 for (Map.Entry<String, List<MDResolvedResource>> entry : matching.entrySet()) {
262260 Message.warn("\t" + entry.getKey());
263261 for (MDResolvedResource c : entry.getValue()) {
264262 Message.warn("\t\t" + c.getRevision()
268266 } else if (requirementStrategy == RequirementStrategy.noambiguity) {
269267 Message.error("Ambiguity for the '" + osgiType + "' requirement "
270268 + mrid.getName() + ";version=" + mrid.getRevision());
271 for (Entry<String, List<MDResolvedResource>> entry : matching.entrySet()) {
269 for (Map.Entry<String, List<MDResolvedResource>> entry : matching.entrySet()) {
272270 Message.error("\t" + entry.getKey());
273271 for (MDResolvedResource c : entry.getValue()) {
274272 Message.error("\t\t" + c.getRevision()
288286 return found;
289287 }
290288
289 @Override
291290 public ResolvedResource findArtifactRef(Artifact artifact, Date date) {
292291 URL url = artifact.getUrl();
293292 if (url == null) {
296295 }
297296 Message.verbose("\tusing url for " + artifact + ": " + url);
298297 logArtifactAttempt(artifact, url.toExternalForm());
299 Resource resource = new URLResource(url);
298 final Resource resource = new URLResource(url, this.getTimeoutConstraint());
300299 return new ResolvedResource(resource, artifact.getModuleRevisionId().getRevision());
301300 }
302301
312311 }
313312
314313 @Override
315 protected Collection/* <String> */filterNames(Collection/* <String> */names) {
314 protected Collection<String> filterNames(Collection<String> names) {
316315 getSettings().filterIgnore(names);
317316 return names;
318317 }
319318
320319 @Override
321 protected Collection findNames(Map tokenValues, String token) {
320 protected Collection<String> findNames(Map<String, String> tokenValues, String token) {
322321 if (IvyPatternHelper.ORGANISATION_KEY.equals(token)) {
323322 return getRepoDescriptor().getCapabilities();
324323 }
325324
326 String osgiType = (String) tokenValues.get(IvyPatternHelper.ORGANISATION_KEY);
327 if (osgiType == null || osgiType.length() == 0) {
328 return Collections.EMPTY_LIST;
325 String osgiType = tokenValues.get(IvyPatternHelper.ORGANISATION_KEY);
326 if (isNullOrEmpty(osgiType)) {
327 return Collections.emptyList();
329328 }
330329
331330 if (IvyPatternHelper.MODULE_KEY.equals(token)) {
333332 }
334333
335334 if (IvyPatternHelper.REVISION_KEY.equals(token)) {
336 String name = (String) tokenValues.get(IvyPatternHelper.MODULE_KEY);
337 List<String> versions = new ArrayList<String>();
335 String name = tokenValues.get(IvyPatternHelper.MODULE_KEY);
336 List<String> versions = new ArrayList<>();
338337 Set<ModuleDescriptorWrapper> mds = getRepoDescriptor().findModules(osgiType, name);
339338 if (mds != null) {
340339 for (ModuleDescriptorWrapper md : mds) {
345344 }
346345
347346 if (IvyPatternHelper.CONF_KEY.equals(token)) {
348 String name = (String) tokenValues.get(IvyPatternHelper.MODULE_KEY);
347 String name = tokenValues.get(IvyPatternHelper.MODULE_KEY);
349348 if (name == null) {
350 return Collections.EMPTY_LIST;
349 return Collections.emptyList();
351350 }
352351 if (osgiType.equals(BundleInfo.PACKAGE_TYPE)) {
353352 return Collections.singletonList(BundleInfoAdapter.CONF_USE_PREFIX + name);
355354 Collection<ModuleDescriptor> mds = ModuleDescriptorWrapper.unwrap(getRepoDescriptor()
356355 .findModules(osgiType, name));
357356 if (mds == null) {
358 return Collections.EMPTY_LIST;
359 }
360 String version = (String) tokenValues.get(IvyPatternHelper.REVISION_KEY);
357 return Collections.emptyList();
358 }
359 String version = tokenValues.get(IvyPatternHelper.REVISION_KEY);
361360 if (version == null) {
362 return Collections.EMPTY_LIST;
361 return Collections.emptyList();
363362 }
364363 ModuleDescriptor found = null;
365364 for (ModuleDescriptor md : mds) {
368367 }
369368 }
370369 if (found == null) {
371 return Collections.EMPTY_LIST;
372 }
373 List<String> confs = Arrays.asList(found.getConfigurationsNames());
374 return confs;
375 }
376 return Collections.EMPTY_LIST;
370 return Collections.emptyList();
371 }
372 return Arrays.asList(found.getConfigurationsNames());
373 }
374 return Collections.emptyList();
377375 }
378376
379377 /**
380378 * Populate capabilityValues with capability values for which at least one module match the
381379 * expected revision
382380 */
381 @SuppressWarnings("unused")
383382 private void filterCapabilityValues(Set<String> capabilityValues,
384 Map<String, Set<ModuleDescriptor>> moduleByCapbilityValue,
383 Map<String, Set<ModuleDescriptor>> moduleByCapabilityValue,
385384 Map<String, String> tokenValues, String rev) {
386385 if (rev == null) {
387386 // no revision, all match then
388 capabilityValues.addAll(moduleByCapbilityValue.keySet());
387 capabilityValues.addAll(moduleByCapabilityValue.keySet());
389388 } else {
390 for (Entry<String, Set<ModuleDescriptor>> entry : moduleByCapbilityValue.entrySet()) {
391 Iterator<ModuleDescriptor> itModules = entry.getValue().iterator();
389 for (Map.Entry<String, Set<ModuleDescriptor>> entry : moduleByCapabilityValue.entrySet()) {
392390 boolean moduleMatchRev = false;
393 while (!moduleMatchRev && itModules.hasNext()) {
394 ModuleDescriptor md = itModules.next();
391 for (ModuleDescriptor md : entry.getValue()) {
395392 moduleMatchRev = rev.equals(md.getRevision());
393 if (moduleMatchRev) {
394 break;
395 }
396396 }
397397 if (moduleMatchRev) {
398398 // at least one module matched, the capability value is ok to add
402402 }
403403 }
404404
405 @Override
406 public Map[] listTokenValues(String[] tokens, Map criteria) {
407 Set<String> tokenSet = new HashSet<String>(Arrays.asList(tokens));
405 @SuppressWarnings("unchecked")
406 @Override
407 public Map<String, String>[] listTokenValues(String[] tokens, Map<String, Object> criteria) {
408 Set<String> tokenSet = new HashSet<>(Arrays.asList(tokens));
408409 Set<Map<String, String>> listTokenValues = listTokenValues(tokenSet, criteria);
409410 return listTokenValues.toArray(new Map[listTokenValues.size()]);
410411 }
411412
412413 private Set<Map<String, String>> listTokenValues(Set<String> tokens,
413 Map<String, String> criteria) {
414 Map<String, Object> criteria) {
415 Map<String, String> stringCriteria = new HashMap<>();
416 for (Map.Entry<String, Object> entry : criteria.entrySet()) {
417 Object value = entry.getValue();
418 if (!(value instanceof String)) {
419 // no support for matcher for now
420 return Collections.emptySet();
421 }
422 stringCriteria.put(entry.getKey(), (String) value);
423 }
424
414425 if (tokens.isEmpty()) {
415 return Collections.singleton(criteria);
416 }
417
418 Set<String> remainingTokens = new HashSet<String>(tokens);
419
420 Map<String, String> values = new HashMap<String, String>();
426 // no more tokens to resolve
427 return Collections.singleton(stringCriteria);
428 }
429
430 Set<String> remainingTokens = new HashSet<>(tokens);
421431
422432 remainingTokens.remove(IvyPatternHelper.ORGANISATION_KEY);
423 String osgiType = criteria.get(IvyPatternHelper.ORGANISATION_KEY);
424 if (osgiType == null || osgiType.length() == 0) {
425 return Collections.emptySet();
426 }
427 values.put(IvyPatternHelper.ORGANISATION_KEY, osgiType);
428
433 String osgiType = stringCriteria.get(IvyPatternHelper.ORGANISATION_KEY);
429434 if (osgiType == null) {
430 Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
431 Map<String, String> newCriteria = new HashMap<String, String>(criteria);
435 Map<String, Object> newCriteria = new HashMap<>(criteria);
432436 newCriteria.put(IvyPatternHelper.ORGANISATION_KEY, BundleInfo.BUNDLE_TYPE);
433 tokenValues.addAll(listTokenValues(remainingTokens, newCriteria));
434 newCriteria = new HashMap<String, String>(criteria);
437 Set<Map<String, String>> tokenValues = new HashSet<>(listTokenValues(remainingTokens,
438 newCriteria));
439 newCriteria = new HashMap<>(criteria);
435440 newCriteria.put(IvyPatternHelper.ORGANISATION_KEY, BundleInfo.PACKAGE_TYPE);
436441 tokenValues.addAll(listTokenValues(remainingTokens, newCriteria));
437 newCriteria = new HashMap<String, String>(criteria);
442 newCriteria = new HashMap<>(criteria);
438443 newCriteria.put(IvyPatternHelper.ORGANISATION_KEY, BundleInfo.SERVICE_TYPE);
439444 tokenValues.addAll(listTokenValues(remainingTokens, newCriteria));
440445 return tokenValues;
441446 }
442447
448 Map<String, String> values = new HashMap<>();
449 values.put(IvyPatternHelper.ORGANISATION_KEY, osgiType);
450
443451 Set<String> capabilities = getRepoDescriptor().getCapabilityValues(osgiType);
444452 if (capabilities == null || capabilities.isEmpty()) {
445453 return Collections.emptySet();
446454 }
447455
448456 remainingTokens.remove(IvyPatternHelper.MODULE_KEY);
449 String module = criteria.get(IvyPatternHelper.MODULE_KEY);
457 String module = stringCriteria.get(IvyPatternHelper.MODULE_KEY);
450458 if (module == null) {
451 Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
459 Set<Map<String, String>> tokenValues = new HashSet<>();
452460 for (String name : capabilities) {
453 Map<String, String> newCriteria = new HashMap<String, String>(criteria);
461 Map<String, Object> newCriteria = new HashMap<>(criteria);
454462 newCriteria.put(IvyPatternHelper.MODULE_KEY, name);
455463 tokenValues.addAll(listTokenValues(remainingTokens, newCriteria));
456464 }
459467 values.put(IvyPatternHelper.MODULE_KEY, module);
460468
461469 remainingTokens.remove(IvyPatternHelper.REVISION_KEY);
462 String rev = criteria.get(IvyPatternHelper.REVISION_KEY);
470 String rev = stringCriteria.get(IvyPatternHelper.REVISION_KEY);
463471 if (rev == null) {
464472 Set<ModuleDescriptorWrapper> mdws = getRepoDescriptor().findModules(osgiType, module);
465473 if (mdws == null || mdws.isEmpty()) {
466474 return Collections.emptySet();
467475 }
468 Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
476 Set<Map<String, String>> tokenValues = new HashSet<>();
469477 for (ModuleDescriptorWrapper mdw : mdws) {
470 Map<String, String> newCriteria = new HashMap<String, String>(criteria);
478 Map<String, Object> newCriteria = new HashMap<>(criteria);
471479 newCriteria.put(IvyPatternHelper.REVISION_KEY, mdw.getBundleInfo().getVersion()
472480 .toString());
473481 tokenValues.addAll(listTokenValues(remainingTokens, newCriteria));
477485 values.put(IvyPatternHelper.REVISION_KEY, rev);
478486
479487 remainingTokens.remove(IvyPatternHelper.CONF_KEY);
480 String conf = criteria.get(IvyPatternHelper.CONF_KEY);
488 String conf = stringCriteria.get(IvyPatternHelper.CONF_KEY);
481489 if (conf == null) {
482490 if (osgiType.equals(BundleInfo.PACKAGE_TYPE)) {
483491 values.put(IvyPatternHelper.CONF_KEY, BundleInfoAdapter.CONF_USE_PREFIX + module);
488496 if (bundles == null) {
489497 return Collections.emptySet();
490498 }
491 Version v;
492 try {
493 v = new Version(rev);
494 } catch (ParseException e) {
495 return Collections.emptySet();
496 }
499 Version v = new Version(rev);
497500 ModuleDescriptorWrapper found = null;
498501 for (ModuleDescriptorWrapper bundle : bundles) {
499502 if (bundle.getBundleInfo().getVersion().equals(v)) {
503506 if (found == null) {
504507 return Collections.emptySet();
505508 }
506 Set<Map<String, String>> tokenValues = new HashSet<Map<String, String>>();
509 Set<Map<String, String>> tokenValues = new HashSet<>();
507510 List<String> configurations = BundleInfoAdapter
508511 .getConfigurations(found.getBundleInfo());
509 for (int i = 0; i < configurations.size(); i++) {
510 Map<String, String> newCriteria = new HashMap<String, String>(criteria);
511 newCriteria.put(IvyPatternHelper.CONF_KEY, configurations.get(i));
512 for (String configuration : configurations) {
513 Map<String, String> newCriteria = new HashMap<>(stringCriteria);
514 newCriteria.put(IvyPatternHelper.CONF_KEY, configuration);
512515 tokenValues.add(newCriteria);
513516 }
514517 return tokenValues;
518521 return Collections.singleton(values);
519522 }
520523
524 @Override
521525 protected long get(Resource resource, File dest) throws IOException {
522526 Message.verbose("\t" + getName() + ": downloading " + resource.getName());
523527 Message.debug("\t\tto " + dest);
528532 return dest.length();
529533 }
530534
535 @Override
531536 protected Resource getResource(String source) throws IOException {
532537 return getRepository().getResource(source);
533538 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 public class AggregatedOSGiResolver extends AbstractOSGiResolver {
2323
24 private List<AbstractOSGiResolver> resolvers = new ArrayList<AbstractOSGiResolver>();
24 private List<AbstractOSGiResolver> resolvers = new ArrayList<>();
2525
2626 public void add(AbstractOSGiResolver resolver) {
2727 resolvers.add(resolver);
2929
3030 @Override
3131 protected void init() {
32 List<RepoDescriptor> repos = new ArrayList<RepoDescriptor>();
32 List<RepoDescriptor> repos = new ArrayList<>();
3333 for (AbstractOSGiResolver resolver : resolvers) {
3434 repos.add(resolver.getRepoDescriptor());
3535 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
7474
7575 @Override
7676 public Set<String> getCapabilities() {
77 Set<String> ret = new HashSet<String>();
77 Set<String> ret = new HashSet<>();
7878 for (RepoDescriptor repo : repos) {
7979 Set<String> capabilities = repo.getCapabilities();
8080 if (capabilities != null) {
8686
8787 @Override
8888 public Set<ModuleDescriptorWrapper> findModules(String requirement, String value) {
89 Set<ModuleDescriptorWrapper> ret = new HashSet<ModuleDescriptorWrapper>();
89 Set<ModuleDescriptorWrapper> ret = new HashSet<>();
9090 for (RepoDescriptor repo : repos) {
9191 Set<ModuleDescriptorWrapper> modules = repo.findModules(requirement, value);
9292 if (modules != null) {
9898
9999 @Override
100100 public Set<String> getCapabilityValues(String capabilityName) {
101 Set<String> ret = new HashSet<String>();
101 Set<String> ret = new HashSet<>();
102102 for (RepoDescriptor repo : repos) {
103103 Set<String> capabilityValues = repo.getCapabilityValues(capabilityName);
104104 if (capabilityValues != null) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3636
3737 public class ArtifactReportManifestIterable implements Iterable<ManifestAndLocation> {
3838
39 private final Map<ModuleRevisionId, List<ArtifactDownloadReport>> artifactReports = new HashMap<ModuleRevisionId, List<ArtifactDownloadReport>>();
39 private final Map<ModuleRevisionId, List<ArtifactDownloadReport>> artifactReports = new HashMap<>();
4040
4141 private List<String> sourceTypes;
4242
4747 ModuleRevisionId mrid = report.getArtifact().getModuleRevisionId();
4848 List<ArtifactDownloadReport> moduleReports = artifactReports.get(mrid);
4949 if (moduleReports == null) {
50 moduleReports = new ArrayList<ArtifactDownloadReport>();
50 moduleReports = new ArrayList<>();
5151 artifactReports.put(mrid, moduleReports);
5252 }
5353 moduleReports.add(report);
7171 public boolean hasNext() {
7272 while (next == null && it.hasNext()) {
7373 ModuleRevisionId mrid = it.next();
74 List<ArtifactDownloadReport> reports = artifactReports.get(mrid);
7574 ArtifactDownloadReport jar = null;
7675 ArtifactDownloadReport source = null;
77 for (ArtifactDownloadReport report : reports) {
76 for (ArtifactDownloadReport report : artifactReports.get(mrid)) {
7877 if (sourceTypes != null && sourceTypes.contains(report.getArtifact().getType())) {
7978 source = report;
8079 } else {
9493 }
9594 }
9695 if (jar.getUnpackedLocalFile() != null && jar.getUnpackedLocalFile().isDirectory()) {
97 FileInputStream in = null;
98 try {
99 in = new FileInputStream(new File(jar.getUnpackedLocalFile(),
100 "META-INF/MANIFEST.MF"));
96 try (FileInputStream in = new FileInputStream(new File(jar.getUnpackedLocalFile(),
97 "META-INF/MANIFEST.MF"))) {
10198 next = new ManifestAndLocation(new Manifest(in), jar.getUnpackedLocalFile()
10299 .toURI(), sourceURI);
103100 return true;
104101 } catch (FileNotFoundException e) {
105102 Message.debug(
106 "Bundle directory file just removed: " + jar.getUnpackedLocalFile(), e);
103 "Bundle directory file just removed: " + jar.getUnpackedLocalFile(), e);
107104 } catch (IOException e) {
108105 Message.debug("The Manifest in the bundle directory could not be read: "
109106 + jar.getUnpackedLocalFile(), e);
110 } finally {
111 if (in != null) {
112 try {
113 in.close();
114 } catch (IOException e) {
115 // ignore
116 }
117 }
118107 }
119108 } else {
120109 File artifact;
123112 } else {
124113 artifact = jar.getLocalFile();
125114 }
126 JarInputStream in = null;
127 try {
128 in = new JarInputStream(new FileInputStream(artifact));
115 try (JarInputStream in = new JarInputStream(new FileInputStream(artifact))) {
129116 Manifest manifest = in.getManifest();
130117 if (manifest != null) {
131118 next = new ManifestAndLocation(manifest, artifact.toURI(), sourceURI);
136123 Message.debug("Jar file just removed: " + artifact, e);
137124 } catch (IOException e) {
138125 Message.warn("Unreadable jar: " + artifact, e);
139 } finally {
140 if (in != null) {
141 try {
142 in.close();
143 } catch (IOException e) {
144 // Don't care
145 }
146 }
147126 }
148127 }
149128 }
150 if (next == null) {
151 return false;
152 }
153 return true;
129 return next != null;
154130 }
155131
156132 public ManifestAndLocation next() {
168144
169145 }
170146
171 }
147 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5353 return version;
5454 }
5555
56 }
56 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232
3333 public class EditableRepoDescriptor extends RepoDescriptor {
3434
35 private final Map<String, Map<String, Set<ModuleDescriptorWrapper>>> moduleByCapabilities = new HashMap<String, Map<String, Set<ModuleDescriptorWrapper>>>();
35 private final Map<String, Map<String, Set<ModuleDescriptorWrapper>>> moduleByCapabilities = new HashMap<>();
3636
37 private final Set<ModuleDescriptorWrapper> modules = new HashSet<ModuleDescriptorWrapper>();
37 private final Set<ModuleDescriptorWrapper> modules = new HashSet<>();
3838
3939 private final ExecutionEnvironmentProfileProvider profileProvider;
4040
101101 modules.add(md);
102102 Map<String, Set<ModuleDescriptorWrapper>> map = moduleByCapabilities.get(type);
103103 if (map == null) {
104 map = new HashMap<String, Set<ModuleDescriptorWrapper>>();
104 map = new HashMap<>();
105105 moduleByCapabilities.put(type, map);
106106 }
107107 Set<ModuleDescriptorWrapper> bundleReferences = map.get(value);
108108 if (bundleReferences == null) {
109 bundleReferences = new HashSet<ModuleDescriptorWrapper>();
109 bundleReferences = new HashSet<>();
110110 map.put(value, bundleReferences);
111111 }
112112 if (!bundleReferences.add(md)) {
149149
150150 @Override
151151 public boolean equals(Object obj) {
152 if (!(obj instanceof EditableRepoDescriptor)) {
153 return false;
154 }
152155 if (this == obj) {
153156 return true;
154157 }
155 if (obj == null) {
156 return false;
157 }
158 if (getClass() != obj.getClass()) {
159 return false;
160 }
161158 EditableRepoDescriptor other = (EditableRepoDescriptor) obj;
162 if (modules == null) {
163 if (other.modules != null) {
164 return false;
165 }
166 } else if (!modules.equals(other.modules)) {
167 return false;
168 }
169 return true;
159 return modules == null ? other.modules == null : modules.equals(other.modules);
170160 }
171161
172162 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.FileInputStream;
2222 import java.io.FileNotFoundException;
2323 import java.io.FilenameFilter;
24 import java.io.IOException;
2425 import java.io.InputStream;
2526 import java.net.MalformedURLException;
2627 import java.net.URI;
3536 /**
3637 * List of directory name that usually contains jars but are not bundles
3738 */
38 public static final Set<String> NON_BUNDLE_DIRS = new HashSet<String>(Arrays.asList("source",
39 "sources", "javadoc", "javadocs", "doc", "docs"));
39 public static final Set<String> NON_BUNDLE_DIRS = new HashSet<>(Arrays.asList("source",
40 "sources", "javadoc", "javadocs", "doc", "docs"));
4041
4142 /**
4243 * Default directory filter that doesn't select .svn directories, neither the directories that
5152 /**
5253 * Default bundle filter that select only .jar files
5354 */
54 public static final FilenameFilter DEFAULT_BUNLDE_FILTER = new FilenameFilter() {
55 public static final FilenameFilter DEFAULT_BUNDLE_FILTER = new FilenameFilter() {
5556 public boolean accept(File dir, String name) {
5657 return name.endsWith(".jar");
5758 }
5859 };
5960
61 /**
62 * Deprecated because of renaming due spell check.
63 */
64 @Deprecated
65 public static final FilenameFilter DEFAULT_BUNLDE_FILTER = DEFAULT_BUNDLE_FILTER;
66
6067 private FilenameFilter dirFilter = DEFAULT_DIR_FILTER;
6168
62 private FilenameFilter bundleFilter = DEFAULT_BUNLDE_FILTER;
69 private FilenameFilter bundleFilter = DEFAULT_BUNDLE_FILTER;
6370
6471 /**
6572 * Default constructor
66 *
73 *
6774 * @param root
6875 * the root directory of the file system to lookup
6976 */
101108 return new FileInputStream(f);
102109 }
103110
104 protected List<File> listBundleFiles(File dir) {
111 protected List<File> listBundleFiles(File dir) throws IOException {
105112 return Arrays.asList(dir.listFiles(new FileFilter() {
106113 public boolean accept(File f) {
107 if (!f.isFile()) {
108 return false;
109 }
110 return bundleFilter.accept(f.getParentFile(), f.getName());
114 return f.isFile() && bundleFilter.accept(f.getParentFile(), f.getName());
111115 }
112116 }));
113117 }
114118
115 protected List<File> listDirs(File dir) {
119 protected List<File> listDirs(File dir) throws IOException {
116120 return Arrays.asList(dir.listFiles(new FileFilter() {
117121 public boolean accept(File f) {
118 if (!f.isDirectory()) {
119 return false;
120 }
121 return dirFilter == null || dirFilter.accept(f.getParentFile(), f.getName());
122 return f.isDirectory() && (dirFilter == null || dirFilter.accept(f.getParentFile(), f.getName()));
122123 }
123124 }));
124125 }
125 }
126 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3333
3434 private BundleInfo bundleInfo;
3535
36 private DefaultModuleDescriptor md;
36 private volatile DefaultModuleDescriptor md;
3737
3838 private URI baseUri;
3939
7070 if (collection.isEmpty()) {
7171 return Collections.emptyList();
7272 }
73 List<ModuleDescriptor> unwrapped = new ArrayList<ModuleDescriptor>();
73 List<ModuleDescriptor> unwrapped = new ArrayList<>();
7474 for (ModuleDescriptorWrapper wrapped : collection) {
7575 unwrapped.add(wrapped.getModuleDescriptor());
7676 }
8484
8585 @Override
8686 public boolean equals(Object obj) {
87 if (obj == null || !(obj instanceof ModuleDescriptorWrapper)) {
88 return false;
89 }
90 return bundleInfo.equals(((ModuleDescriptorWrapper) obj).bundleInfo);
87 return obj instanceof ModuleDescriptorWrapper
88 && bundleInfo.equals(((ModuleDescriptorWrapper) obj).bundleInfo);
9189 }
9290
9391 @Override
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.util.HashMap;
2424 import java.util.Map;
2525
26 import org.apache.ivy.core.settings.TimeoutConstraint;
2627 import org.apache.ivy.plugins.repository.Resource;
2728 import org.apache.ivy.plugins.repository.url.URLRepository;
2829 import org.apache.ivy.plugins.repository.url.URLResource;
3637 baseUrl = null;
3738 }
3839
40 /**
41 *
42 * @param baseUrl ditto
43 * @deprecated Since 2.5. Use {@link #RelativeURLRepository(URL, TimeoutConstraint)} instead
44 */
45 @Deprecated
3946 public RelativeURLRepository(URL baseUrl) {
40 super();
47 this(baseUrl, null);
48 }
49
50 public RelativeURLRepository(final URL baseUrl, final TimeoutConstraint timeoutConstraint) {
51 super(timeoutConstraint);
4152 this.baseUrl = baseUrl;
4253 }
4354
44 private Map<String, Resource> resourcesCache = new HashMap<String, Resource>();
55
56 private Map<String, Resource> resourcesCache = new HashMap<>();
4557
4658 public Resource getResource(String source) throws IOException {
4759 source = encode(source);
5163 try {
5264 uri = new URI(source);
5365 } catch (URISyntaxException e) {
54 // very wierd URL, let's assume it is absolute
66 // very weird URL, let's assume it is absolute
5567 uri = null;
5668 }
5769 if (uri == null || uri.isAbsolute()) {
58 res = new URLResource(new URL(source));
70 res = new URLResource(new URL(source), getTimeoutConstraint());
5971 } else {
60 res = new URLResource(new URL(baseUrl + source));
72 res = new URLResource(new URL(baseUrl + source), getTimeoutConstraint());
6173 }
6274 resourcesCache.put(source, res);
6375 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 public abstract class RepoDescriptor {
2323
24 abstract public Iterator<ModuleDescriptorWrapper> getModules();
24 public abstract Iterator<ModuleDescriptorWrapper> getModules();
2525
26 abstract public Set<String> getCapabilities();
26 public abstract Set<String> getCapabilities();
2727
28 abstract public Set<ModuleDescriptorWrapper> findModules(String requirement, String value);
28 public abstract Set<ModuleDescriptorWrapper> findModules(String requirement, String value);
2929
30 abstract public Set<String> getCapabilityValues(String capabilityName);
30 public abstract Set<String> getCapabilityValues(String capabilityName);
3131
3232 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535
3636 /**
3737 * Default constructor
38 *
39 * @param root
38 *
39 * @param repo
4040 * the root directory of the file system to lookup
4141 */
4242 public RepositoryManifestIterable(Repository repo) {
6767 }
6868
6969 private List<String> asList(String[] array) {
70 return array == null ? Collections.<String> emptyList() : Arrays.<String> asList(array);
70 if (array == null) {
71 return Collections.emptyList();
72 }
73 return Arrays.asList(array);
7174 }
7275 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
201201 }
202202 }
203203
204 }
204 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3131 import org.apache.ivy.core.event.EventManager;
3232 import org.apache.ivy.core.report.ArtifactDownloadReport;
3333 import org.apache.ivy.core.report.DownloadStatus;
34 import org.apache.ivy.core.settings.TimeoutConstraint;
3435 import org.apache.ivy.osgi.core.ExecutionEnvironmentProfileProvider;
3536 import org.apache.ivy.osgi.p2.P2ArtifactParser;
3637 import org.apache.ivy.osgi.p2.P2CompositeParser;
5657
5758 private final CacheResourceOptions options;
5859
60 private final TimeoutConstraint timeoutConstraint;
61
5962 private int logLevel = Message.MSG_INFO;
6063
61 public UpdateSiteLoader(RepositoryCacheManager repositoryCacheManager,
62 EventManager eventManager, CacheResourceOptions options) {
64 public UpdateSiteLoader(final RepositoryCacheManager repositoryCacheManager,
65 final EventManager eventManager, final CacheResourceOptions options,
66 final TimeoutConstraint timeoutConstraint) {
6367 this.repositoryCacheManager = repositoryCacheManager;
6468 this.options = options;
69 this.timeoutConstraint = timeoutConstraint;
6570 if (eventManager != null) {
6671 urlRepository.addTransferListener(eventManager);
6772 }
176181 InputStream readIn = null; // the input stream from which the xml should be read
177182
178183 URL contentUrl = repoUri.resolve(baseName + ".jar").toURL();
179 URLResource res = new URLResource(contentUrl);
184 URLResource res = new URLResource(contentUrl, this.timeoutConstraint);
180185
181186 ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
182187 baseName, baseName, "jar", options, urlRepository);
184189 if (report.getDownloadStatus() == DownloadStatus.FAILED) {
185190 // no jar file, try the xml one
186191 contentUrl = repoUri.resolve(baseName + ".xml").toURL();
187 res = new URLResource(contentUrl);
192 res = new URLResource(contentUrl, this.timeoutConstraint);
188193
189194 report = repositoryCacheManager.downloadRepositoryResource(res, baseName, baseName,
190195 "xml", options, urlRepository);
221226 return true;
222227 }
223228
224 private UpdateSite loadSite(URI repoUri) throws IOException, ParseException, SAXException {
229 private UpdateSite loadSite(URI repoUri) throws IOException, SAXException {
225230 URI siteUri = normalizeSiteUri(repoUri, null);
226231 URL u = siteUri.resolve("site.xml").toURL();
227232
228 URLResource res = new URLResource(u);
233 final URLResource res = new URLResource(u, this.timeoutConstraint);
229234 ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
230235 "site", "updatesite", "xml", options, urlRepository);
231236 if (report.getDownloadStatus() == DownloadStatus.FAILED) {
232237 return null;
233238 }
234 InputStream in = new FileInputStream(report.getLocalFile());
235 try {
239 try (InputStream in = new FileInputStream(report.getLocalFile())) {
236240 UpdateSite site = EclipseUpdateSiteParser.parse(in);
237241 site.setUri(normalizeSiteUri(site.getUri(), siteUri));
238242 return site;
239 } finally {
240 in.close();
241243 }
242244 }
243245
264266 }
265267
266268 private UpdateSiteDescriptor loadFromDigest(UpdateSite site) throws IOException,
267 ParseException, SAXException {
269 SAXException {
268270 URI digestBaseUri = site.getDigestUri();
269271 if (digestBaseUri == null) {
270272 digestBaseUri = site.getUri();
274276 URL digest = digestBaseUri.resolve("digest.zip").toURL();
275277 Message.verbose("\tReading " + digest);
276278
277 URLResource res = new URLResource(digest);
279 final URLResource res = new URLResource(digest, this.timeoutConstraint);
278280 ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
279281 "digest", "digest", "zip", options, urlRepository);
280282 if (report.getDownloadStatus() == DownloadStatus.FAILED) {
281283 return null;
282284 }
283 InputStream in = new FileInputStream(report.getLocalFile());
284 try {
285 try (InputStream in = new FileInputStream(report.getLocalFile())) {
285286 ZipInputStream zipped = findEntry(in, "digest.xml");
286287 if (zipped == null) {
287288 return null;
288289 }
289290 return UpdateSiteDigestParser.parse(zipped, site);
290 } finally {
291 in.close();
292 }
293 }
294
295 private UpdateSiteDescriptor loadFromSite(UpdateSite site) throws IOException, ParseException,
296 SAXException {
291 }
292 }
293
294 private UpdateSiteDescriptor loadFromSite(UpdateSite site) throws IOException, SAXException {
297295 UpdateSiteDescriptor repoDescriptor = new UpdateSiteDescriptor(site.getUri(),
298296 ExecutionEnvironmentProfileProvider.getInstance());
299297
300298 for (EclipseFeature feature : site.getFeatures()) {
301299 URL url = site.getUri().resolve(feature.getUrl()).toURL();
302300
303 URLResource res = new URLResource(url);
301 final URLResource res = new URLResource(url, this.timeoutConstraint);
304302 ArtifactDownloadReport report = repositoryCacheManager.downloadRepositoryResource(res,
305303 feature.getId(), "feature", "jar", options, urlRepository);
306304 if (report.getDownloadStatus() == DownloadStatus.FAILED) {
307305 return null;
308306 }
309 InputStream in = new FileInputStream(report.getLocalFile());
310 try {
307 try (InputStream in = new FileInputStream(report.getLocalFile())) {
311308 ZipInputStream zipped = findEntry(in, "feature.xml");
312309 if (zipped == null) {
313310 return null;
315312 EclipseFeature f = FeatureParser.parse(zipped);
316313 f.setURL(feature.getUrl());
317314 repoDescriptor.addFeature(f);
318 } finally {
319 in.close();
320315 }
321316 }
322317
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6666 }
6767 CacheResourceOptions options = new CacheResourceOptions();
6868 if (metadataTtl != null) {
69 options.setTtl(metadataTtl.longValue());
69 options.setTtl(metadataTtl);
7070 }
7171 if (forceMetadataUpdate != null) {
72 options.setForce(forceMetadataUpdate.booleanValue());
72 options.setForce(forceMetadataUpdate);
7373 }
7474 final int log;
7575 if (logLevel != null) {
114114 }
115115 }
116116 });
117 UpdateSiteLoader loader = new UpdateSiteLoader(getRepositoryCacheManager(),
118 getEventManager(), options);
117 final UpdateSiteLoader loader = new UpdateSiteLoader(getRepositoryCacheManager(),
118 getEventManager(), options, this.getTimeoutConstraint());
119119 loader.setLogLevel(log);
120120 RepoDescriptor repoDescriptor;
121121 try {
126126 } catch (ParseException e) {
127127 throw new RuntimeException("Failed to parse the updatesite (" + e.getMessage() + ")", e);
128128 } catch (SAXException e) {
129 throw new RuntimeException("Illformed updatesite (" + e.getMessage() + ")", e);
129 throw new RuntimeException("Ill-formed updatesite (" + e.getMessage() + ")", e);
130130 } catch (URISyntaxException e) {
131 throw new RuntimeException("Illformed url (" + e.getMessage() + ")", e);
131 throw new RuntimeException("Ill-formed url (" + e.getMessage() + ")", e);
132132 }
133133 if (repoDescriptor == null) {
134134 setRepoDescriptor(FAILING_REPO_DESCRIPTOR);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727
2828 private Version version;
2929
30 private List<EclipsePlugin> plugins = new ArrayList<EclipsePlugin>();
30 private List<EclipsePlugin> plugins = new ArrayList<>();
3131
32 private List<Require> requires = new ArrayList<Require>();
32 private List<Require> requires = new ArrayList<>();
3333
3434 private String url;
3535
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.InputStream;
2222 import java.net.URI;
2323 import java.net.URISyntaxException;
24 import java.text.ParseException;
2524
2625 import javax.xml.parsers.ParserConfigurationException;
2726
3130 import org.xml.sax.Attributes;
3231 import org.xml.sax.SAXException;
3332
33 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
34
3435 public class EclipseUpdateSiteParser {
3536
36 public static UpdateSite parse(InputStream in) throws ParseException, IOException, SAXException {
37 public static UpdateSite parse(InputStream in) throws IOException, SAXException {
3738 SiteHandler handler = new SiteHandler();
3839 try {
3940 XMLHelper.parse(in, null, handler, null);
6263 public SiteHandler() {
6364 super(SITE);
6465 // addChild(new DescriptionHandler(), new ChildElementHandler() {
65 // public void childHanlded(DelegetingHandler child) {
66 // public void childHandled(DelegatingHandler child) {
6667 // updateSite.setDescription(child.getBufferedChars().trim());
6768 // }
6869 // });
6970 addChild(new FeatureHandler(), new ChildElementHandler<FeatureHandler>() {
70 public void childHanlded(FeatureHandler child) {
71 @Override
72 public void childHandled(FeatureHandler child) {
7173 updatesite.addFeature(child.feature);
7274 }
7375 });
7476 // addChild(new ArchiveHandler(), new ChildElementHandler() {
75 // public void childHanlded(DelegetingHandler child) {
77 // public void childHandled(DelegatingHandler child) {
7678 // updateSite.addArchive(((ArchiveHandler) child).archive);
7779 // }
7880 // });
7981 // addChild(new CategoryDefHandler(), new ChildElementHandler() {
80 // public void childHanlded(DelegetingHandler child) {
82 // public void childHandled(DelegatingHandler child) {
8183 // updateSite.addCategoryDef(((CategoryDefHandler) child).categoryDef);
8284 // }
8385 // });
8486 }
8587
88 @Override
8689 protected void handleAttributes(Attributes atts) {
8790 updatesite = new UpdateSite();
8891
8992 String url = atts.getValue(URL);
90 if (url != null && !("".equals(url.trim()))) {
93 if (!isNullOrEmpty(url)) {
9194 if (!url.endsWith("/") && !url.endsWith(File.separator)) {
9295 url += "/";
9396 }
99102 }
100103
101104 String mirrorsURL = atts.getValue(MIRRORS_URL);
102 if (mirrorsURL != null && mirrorsURL.trim().length() > 0) {
105 if (!isNullOrEmpty(mirrorsURL)) {
103106 updatesite.setMirrorsURL(mirrorsURL);
104107 }
105108
106109 String pack200 = atts.getValue(PACK200);
107 if (pack200 != null && new Boolean(pack200).booleanValue()) {
110 if (pack200 != null && Boolean.parseBoolean(pack200)) {
108111 updatesite.setPack200(true);
109112 }
110113
124127 }
125128 }
126129
127 // private static class DescriptionHandler extends DelegetingHandler {
130 // private static class DescriptionHandler extends DelegatingHandler {
128131 //
129132 // private static final String DESCRIPTION = "description";
130133 //
169172 public FeatureHandler() {
170173 super(FEATURE);
171174 addChild(new CategoryHandler(), new ChildElementHandler<CategoryHandler>() {
172 public void childHanlded(CategoryHandler child) {
175 @Override
176 public void childHandled(CategoryHandler child) {
173177 feature.addCategory(child.name);
174178 }
175179 });
176180 }
177181
182 @Override
178183 protected void handleAttributes(Attributes atts) throws SAXException {
179184 String id = atts.getValue(ID);
180185 String version = atts.getValue(VERSION);
181 try {
182 feature = new EclipseFeature(id, new Version(version));
183 } catch (ParseException e) {
184 throw new SAXException("Incorrect version on the feature '" + id + "': " + version
185 + " (" + e.getMessage() + ")");
186 }
186 feature = new EclipseFeature(id, new Version(version));
187187
188188 String url = atts.getValue(URL);
189189 if (url != null) {
212212 super(CATEGORY);
213213 }
214214
215 @Override
215216 protected void handleAttributes(Attributes atts) throws SAXException {
216217 name = atts.getValue(NAME);
217218 }
218219 }
219220
220 // private static class ArchiveHandler extends DelegetingHandler {
221 // private static class ArchiveHandler extends DelegatingHandler {
221222 //
222223 // private static final String ARCHIVE = "archive";
223224 //
243244 // }
244245 // }
245246
246 // private static class CategoryDefHandler extends DelegetingHandler {
247 // private static class CategoryDefHandler extends DelegatingHandler {
247248 //
248249 // private static final String CATEGORY_DEF = "category-def";
249250 //
256257 // public CategoryDefHandler() {
257258 // super(CATEGORY_DEF);
258259 // addChild(new DescriptionHandler(), new ChildElementHandler<DescriptionHandler>() {
259 // public void childHanlded(DescriptionHandler child) {
260 // public void childHandled(DescriptionHandler child) {
260261 // categoryDef.setDescription(child.getBufferedChars().trim());
261262 // }
262263 // });
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.io.IOException;
2020 import java.io.InputStream;
21 import java.text.ParseException;
2221 import java.util.ArrayList;
2322 import java.util.List;
2423
3231
3332 public class FeatureParser {
3433
35 public static EclipseFeature parse(InputStream in) throws ParseException, IOException,
36 SAXException {
34 public static EclipseFeature parse(InputStream in) throws IOException, SAXException {
3735 FeatureHandler handler = new FeatureHandler();
3836 try {
3937 XMLHelper.parse(in, null, handler, null);
8078 public FeatureHandler() {
8179 super(FEATURE);
8280 addChild(new DescriptionHandler(), new ChildElementHandler<DescriptionHandler>() {
83 public void childHanlded(DescriptionHandler child) {
81 @Override
82 public void childHandled(DescriptionHandler child) {
8483 feature.setDescription(child.getBufferedChars().trim());
8584 }
8685 });
8786 addChild(new LicenseHandler(), new ChildElementHandler<LicenseHandler>() {
88 public void childHanlded(LicenseHandler child) {
87 @Override
88 public void childHandled(LicenseHandler child) {
8989 feature.setLicense(child.getBufferedChars().trim());
9090 }
9191 });
9292 addChild(new CopyrightHandler(), new ChildElementHandler<CopyrightHandler>() {
93 public void childHanlded(CopyrightHandler child) {
93 @Override
94 public void childHandled(CopyrightHandler child) {
9495 feature.setCopyright(child.getBufferedChars().trim());
9596 }
9697 });
9798 addChild(new PluginHandler(), new ChildElementHandler<PluginHandler>() {
98 public void childHanlded(PluginHandler child) {
99 @Override
100 public void childHandled(PluginHandler child) {
99101 feature.addPlugin(child.plugin);
100102 }
101103 });
102104 addChild(new RequiresHandler(), new ChildElementHandler<RequiresHandler>() {
103 public void childHanlded(RequiresHandler child) {
105 @Override
106 public void childHandled(RequiresHandler child) {
104107 for (Require require : child.requires) {
105108 feature.addRequire(require);
106109 }
107110 }
108111 });
109112 // addChild(new UrlHandler(), new ChildElementHandler<UrlHandler>() {
110 // public void childHanlded(UrlHandler child) {
113 // public void childHandled(UrlHandler child) {
111114 // }
112115 // });
113116 }
114117
118 @Override
115119 protected void handleAttributes(Attributes atts) throws SAXException {
116120 String id = atts.getValue(ID);
117121 String version = atts.getValue(VERSION);
118 try {
119 feature = new EclipseFeature(id, new Version(version));
120 } catch (ParseException e) {
121 throw new SAXException("Incorrect version on feature '" + id + "': " + version
122 + " (" + e.getMessage() + ")");
123 }
122 feature = new EclipseFeature(id, new Version(version));
124123
125124 feature.setOS(atts.getValue(OS));
126125 feature.setWS(atts.getValue(WS));
128127 feature.setArch(atts.getValue(ARCH));
129128 feature.setApplication(atts.getValue(APPLICATION));
130129 feature.setPlugin(atts.getValue(PLUGIN));
131 feature.setExclusive(Boolean.valueOf(atts.getValue(EXCLUSIVE)).booleanValue());
132 feature.setPrimary(Boolean.valueOf(atts.getValue(PRIMARY)).booleanValue());
130 feature.setExclusive(Boolean.valueOf(atts.getValue(EXCLUSIVE)));
131 feature.setPrimary(Boolean.valueOf(atts.getValue(PRIMARY)));
133132 feature.setColocationAffinity(atts.getValue(COLOCATION_AFFINITY));
134133 feature.setProviderName(atts.getValue(PROVIDER_NAME));
135134 feature.setLabel(atts.getValue(LABEL));
158157 super(PLUGIN);
159158 }
160159
160 @Override
161161 protected void handleAttributes(Attributes atts) throws SAXException {
162162 plugin = new EclipsePlugin();
163163
165165 String version = atts.getValue(VERSION);
166166
167167 plugin.setId(id);
168 try {
169 plugin.setVersion(new Version(version));
170 } catch (ParseException e) {
171 throw new SAXException("Incorrect version on feature's plugin '" + id + "': "
172 + version + " (" + e.getMessage() + ")");
173 }
174 plugin.setUnpack(Boolean.valueOf(atts.getValue(UNPACK)).booleanValue());
168 plugin.setVersion(new Version(version));
169 plugin.setUnpack(Boolean.valueOf(atts.getValue(UNPACK)));
175170 plugin.setFragment(atts.getValue(FRAGMENT));
176171 plugin.setFilter(atts.getValue(FILTER));
177172 }
188183 setBufferingChar(true);
189184 }
190185
186 @Override
191187 protected void handleAttributes(Attributes atts) throws SAXException {
192188 // String url = atts.getValue(URL);
193189 }
204200 setBufferingChar(true);
205201 }
206202
203 @Override
207204 protected void handleAttributes(Attributes atts) throws SAXException {
208205 // String url = atts.getValue(URL);
209206 }
221218 setBufferingChar(true);
222219 }
223220
221 @Override
224222 protected void handleAttributes(Attributes atts) throws SAXException {
225223 // String url = atts.getValue(URL);
226224 }
230228
231229 private static final String REQUIRES = "requires";
232230
233 List<Require> requires = new ArrayList<Require>();
231 List<Require> requires = new ArrayList<>();
234232
235233 public RequiresHandler() {
236234 super(REQUIRES);
237235 addChild(new ImportHandler(), new ChildElementHandler<ImportHandler>() {
238 public void childHanlded(ImportHandler child) {
236 @Override
237 public void childHandled(ImportHandler child) {
239238 requires.add(child.require);
240239 }
241240 });
262261 super(IMPORT);
263262 }
264263
264 @Override
265265 protected void handleAttributes(Attributes atts) throws SAXException {
266266 require = new Require();
267267
269269
270270 require.setFeature(atts.getValue(FEATURE));
271271 require.setPlugin(atts.getValue(PLUGIN));
272 try {
273 require.setVersion(new Version(version));
274 } catch (ParseException e) {
275 throw new SAXException("Incorrect version on feature's import: " + version + " ("
276 + e.getMessage() + ")");
277 }
272 require.setVersion(new Version(version));
278273 require.setMatch(atts.getValue(MATCH));
279274 require.setFilter(atts.getValue(FILTER));
280275 }
281276 }
282277
283 // private static class IncludesHandler extends DelegetingHandler {
278 // private static class IncludesHandler extends DelegatingHandler {
284279 //
285280 // private static final String INCLUDES = "includes";
286281 //
305300 //
306301 // }
307302
308 // private static class InstallHandlerHandler extends DelegetingHandler {
303 // private static class InstallHandlerHandler extends DelegatingHandler {
309304 //
310305 // private static final String INSTALL_HANDLER = "install-handler";
311306 //
327322 //
328323 // }
329324
330 // private static class UrlHandler extends DelegetingHandler {
325 // private static class UrlHandler extends DelegatingHandler {
331326 //
332327 // private static final String URL = "url";
333328 //
334329 // public UrlHandler() {
335330 // super(URL);
336331 // addChild(new UpdateHandler(), new ChildElementHandler<UpdateHandler>() {
337 // public void childHanlded(UpdateHandler child) {
332 // public void childHandled(UpdateHandler child) {
338333 // }
339334 // });
340335 // addChild(new DiscoveryHandler(), new ChildElementHandler<DiscoveryHandler>() {
341 // public void childHanlded(DiscoveryHandler child) {
336 // public void childHandled(DiscoveryHandler child) {
342337 // }
343338 // });
344339 // }
345340 //
346341 // }
347342
348 // private static class UpdateHandler extends DelegetingHandler {
343 // private static class UpdateHandler extends DelegatingHandler {
349344 //
350345 // private static final String UPDATE = "update";
351346 //
364359 //
365360 // }
366361
367 // private static class DiscoveryHandler extends DelegetingHandler {
362 // private static class DiscoveryHandler extends DelegatingHandler {
368363 //
369364 // private static final String DISCOVERY = "discovery";
370365 //
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424
2525 private URI uri;
2626
27 @SuppressWarnings("unused")
2728 private String mirrorsURL;
2829
30 @SuppressWarnings("unused")
2931 private boolean pack200;
3032
3133 private URI digestUri;
3234
33 private List<EclipseFeature> features = new ArrayList<EclipseFeature>();
35 private List<EclipseFeature> features = new ArrayList<>();
3436
3537 public void setUri(URI uri) {
3638 this.uri = uri;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.io.IOException;
2020 import java.io.InputStream;
21 import java.text.ParseException;
2221
2322 import javax.xml.parsers.ParserConfigurationException;
2423
3130
3231 public class UpdateSiteDigestParser {
3332
34 public static UpdateSiteDescriptor parse(InputStream in, UpdateSite site)
35 throws ParseException, IOException, SAXException {
33 public static UpdateSiteDescriptor parse(InputStream in, UpdateSite site) throws IOException,
34 SAXException {
3635 DigestHandler handler = new DigestHandler(site);
3736 try {
3837 XMLHelper.parse(in, null, handler, null);
5352 repoDescriptor = new UpdateSiteDescriptor(site.getUri(),
5453 ExecutionEnvironmentProfileProvider.getInstance());
5554 addChild(new FeatureHandler(), new ChildElementHandler<FeatureHandler>() {
56 public void childHanlded(FeatureHandler child) {
55 @Override
56 public void childHandled(FeatureHandler child) {
5757 repoDescriptor.addFeature(child.feature);
5858 }
5959 });
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3737
3838 DelegatingHandler parent;
3939
40 private final Map<String, DelegatingHandler> saxHandlerMapping = new HashMap<String, DelegatingHandler>();
41
42 private final Map<String, ChildElementHandler<?>> childHandlerMapping = new HashMap<String, DelegatingHandler.ChildElementHandler<?>>();
40 private final Map<String, DelegatingHandler> saxHandlerMapping = new HashMap<>();
41
42 private final Map<String, ChildElementHandler<?>> childHandlerMapping = new HashMap<>();
4343
4444 private final String tagName;
4545
4949
5050 private boolean skipOnError = false;
5151
52 private StringBuffer charBuffer = new StringBuffer();
52 private StringBuilder charBuffer = new StringBuilder();
5353
5454 private boolean bufferingChar = false;
5555
9191 return charBuffer.toString();
9292 }
9393
94 @Override
9495 public void setDocumentLocator(Locator locator) {
9596 this.locator = locator;
9697 for (DelegatingHandler subHandler : saxHandlerMapping.values()) {
105106 /**
106107 * Return an sort of identifier of the current element being parsed. It will only be used for
107108 * logging purpose.
108 *
109 *
109110 * @return an empty string by default
110111 */
111112 protected String getCurrentElementIdentifier() {
123124 parent.delegate = null;
124125 skip = false;
125126 started = false;
126 for (DelegatingHandler/* <?> */subHandler : saxHandlerMapping.values()) {
127 for (DelegatingHandler subHandler : saxHandlerMapping.values()) {
127128 subHandler.stopDelegating();
128129 }
129130 }
130131
131132 private interface SkipOnErrorCallback {
132 public void call() throws SAXException;
133 void call() throws SAXException;
133134 }
134135
135136 private void skipOnError(SkipOnErrorCallback callback) throws SAXException {
145146 }
146147 }
147148
149 @Override
148150 public final void startDocument() throws SAXException {
149151 if (skip) {
150152 return;
157159 }
158160
159161 /**
160 * @throws SAXException
162 * By default do nothing.
163 *
164 * @throws SAXException API told me so
161165 */
162166 protected void doStartDocument() throws SAXException {
163 // by default do nothing
164 }
165
167 }
168
169 @Override
166170 public final void endDocument() throws SAXException {
167171 if (skip) {
168172 return;
175179 }
176180
177181 /**
178 * @throws SAXException
182 * By default do nothing.
183 *
184 * @throws SAXException API told me so
179185 */
180186 protected void doEndDocument() throws SAXException {
181 // by default do nothing
182 }
183
187 }
188
189 @Override
184190 public final void startElement(final String uri, final String localName, final String n,
185191 final Attributes atts) throws SAXException {
186192 // reset the char buffer
226232 }
227233
228234 /**
229 * Called when the expected node is achieved
230 *
235 * Called when the expected node is achieved; nothing to do by default.
236 *
231237 * @param atts
232238 * the xml attributes attached to the expected node
233239 * @exception SAXException
234240 * in case the parsing should be completely stopped
235241 */
236242 protected void handleAttributes(Attributes atts) throws SAXException {
237 // nothing to do by default
238 }
239
240 /**
241 * @throws SAXException
243 }
244
245 /**
246 * By default do nothing.
247 *
248 * @param uri String
249 * @param localName String
250 * @param name String
251 * @param atts Attributes
252 * @throws SAXException API told me so
242253 */
243254 protected void doStartElement(String uri, String localName, String name, Attributes atts)
244255 throws SAXException {
245 // by default do nothing
246 }
247
256 }
257
258 @Override
248259 public final void endElement(final String uri, final String localName, final String n)
249260 throws SAXException {
250261 if (delegate != null) {
261272 if (childHandler != null) {
262273 skipOnError(new SkipOnErrorCallback() {
263274 public void call() throws SAXException {
264 childHandler._childHanlded(savedDelegate);
275 childHandler._childHandled(savedDelegate);
265276 }
266277 });
267278 }
278289 }
279290
280291 /**
281 * @throws SAXException
292 * By default do nothing.
293 *
294 * @param uri String
295 * @param localName String
296 * @param name String
297 * @throws SAXException API told me so
282298 */
283299 protected void doEndElement(String uri, String localName, String name) throws SAXException {
284 // by default do nothing
285 }
286
287 public static abstract class ChildElementHandler<DH extends DelegatingHandler> {
288
289 public abstract void childHanlded(DH child) throws SAXParseException;
300 }
301
302 public abstract static class ChildElementHandler<DH extends DelegatingHandler> {
303
304 /**
305 * @param child DH
306 * @throws SAXParseException on failure
307 * @deprecated because of renaming due spell check.
308 */
309 @Deprecated
310 public void childHanlded(DH child) throws SAXParseException {
311 childHandled(child);
312 }
313
314 public abstract void childHandled(DH child) throws SAXParseException;
290315
291316 // because we know what we're doing
292317 @SuppressWarnings("unchecked")
293 private void _childHanlded(DelegatingHandler delegate) throws SAXParseException {
294 childHanlded((DH) delegate);
295 }
296
297 }
298
318 private void _childHandled(DelegatingHandler delegate) throws SAXParseException {
319 childHandled((DH) delegate);
320 }
321
322 }
323
324 @Override
299325 public final void characters(char[] ch, int start, int length) throws SAXException {
300326 if (skip) {
301327 return;
308334 }
309335
310336 /**
311 * @throws SAXException
337 * @param ch char[]
338 * @param start int
339 * @param length int
340 * @throws SAXException if something goes wrong
312341 */
313342 protected void doCharacters(char[] ch, int start, int length) throws SAXException {
314343 if (bufferingChar) {
316345 }
317346 }
318347
348 @Override
319349 public final void startPrefixMapping(String prefix, String uri) throws SAXException {
320350 if (skip) {
321351 return;
328358 }
329359
330360 /**
331 * @throws SAXException
361 * By default do nothing.
362 *
363 * @param prefix String
364 * @param uri String
365 * @throws SAXException API told me so
332366 */
333367 protected void doStartPrefixMapping(String prefix, String uri) throws SAXException {
334 // by default do nothing
335 }
336
368 }
369
370 @Override
337371 public final void endPrefixMapping(String prefix) throws SAXException {
338372 if (skip) {
339373 return;
346380 }
347381
348382 /**
349 * @throws SAXException
383 * By default do nothing.
384 *
385 * @param prefix String
386 * @throws SAXException API told me so
350387 */
351388 protected void doEndPrefixMapping(String prefix) throws SAXException {
352 // by default do nothing
353 }
354
389 }
390
391 @Override
355392 public final void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
356393 if (skip) {
357394 return;
364401 }
365402
366403 /**
367 * @throws SAXException
404 * By default do nothing
405 *
406 * @param ch char[]
407 * @param start int
408 * @param length int
409 * @throws SAXException API told me so
368410 */
369411 protected void doIgnorableWhitespace(char[] ch, int start, int length) throws SAXException {
370 // by default do nothing
371 }
372
412 }
413
414 @Override
373415 public final void notationDecl(String name, String publicId, String systemId)
374416 throws SAXException {
375417 if (skip) {
383425 }
384426
385427 /**
386 * @throws SAXException
428 * By default do nothing.
429 *
430 * @param name String
431 * @param publicId String
432 * @param systemId String
433 * @throws SAXException API told me so
387434 */
388435 protected void doNotationDecl(String name, String publicId, String systemId)
389436 throws SAXException {
390 // by default do nothing
391 }
392
437 }
438
439 @Override
393440 public final void processingInstruction(String target, String data) throws SAXException {
394441 if (skip) {
395442 return;
402449 }
403450
404451 /**
405 * @throws SAXException
452 * By default do nothing
453 *
454 * @param target String
455 * @param data String
456 * @throws SAXException API told me so
406457 */
407458 protected void doProcessingInstruction(String target, String data) throws SAXException {
408 // by default do nothing
409 }
410
459 }
460
461 @Override
411462 public final void skippedEntity(String name) throws SAXException {
412463 if (skip) {
413464 return;
420471 }
421472
422473 /**
423 * @throws SAXException
474 * By default do nothing.
475 *
476 * @param name String
477 * @throws SAXException API told me so
424478 */
425479 protected void doSkippedEntity(String name) throws SAXException {
426 // by default do nothing
427 }
428
429 /**
430 * @throws SAXException
431 */
480 }
481
482 @Override
432483 public final void unparsedEntityDecl(String name, String publicId, String systemId,
433484 String notationName) throws SAXException {
434485 if (skip) {
442493 }
443494
444495 /**
445 * @throws SAXException
496 * By default do nothing.
497 *
498 * @param name String
499 * @param publicId String
500 * @param systemId String
501 * @param notationName String
502 * @throws SAXException API told me so
446503 */
447504 protected void doUnparsedEntityDecl(String name, String publicId, String systemId,
448505 String notationName) throws SAXException {
449 // by default do nothing
450506 }
451507
452508 // ERROR HANDLING
453509
510 @Override
454511 public final void warning(SAXParseException exception) throws SAXException {
455512 if (skip) {
456513 return;
463520 }
464521
465522 /**
466 * @throws SAXException
523 * By default do nothing.
524 *
525 * @param exception SAXParseException
526 * @throws SAXException API told me so
467527 */
468528 protected void doWarning(SAXParseException exception) throws SAXException {
469 // by default do nothing
470 }
471
529 }
530
531 @Override
472532 public final void error(SAXParseException exception) throws SAXException {
473533 if (skip) {
474534 return;
481541 }
482542
483543 /**
484 * @throws SAXException
544 * By default do nothing.
545 *
546 * @param exception SAXParseException
547 * @throws SAXException API told me so
485548 */
486549 protected void doError(SAXParseException exception) throws SAXException {
487 // by default do nothing
488 }
489
550 }
551
552 @Override
490553 public final void fatalError(SAXParseException exception) throws SAXException {
491554 if (skip) {
492555 return;
499562 }
500563
501564 /**
502 * @throws SAXException
565 * By default do nothing.
566 *
567 * @param exception SAXParseException
568 * @throws SAXException API told me so
503569 */
504570 protected void doFatalError(SAXParseException exception) throws SAXException {
505 // by default do nothing
506571 }
507572
508573 // //////////////////////
525590 return "[line " + locator.getLineNumber() + " col. " + locator.getColumnNumber() + "] ";
526591 }
527592
593 @SuppressWarnings("unused")
528594 private void skipOnError(DelegatingHandler currentHandler,
529595 Class<? extends DelegatingHandler> handlerClassToSkip, String message) {
530596 DelegatingHandler handlerToSkip = currentHandler;
567633 if (value == null) {
568634 return defaultValue;
569635 }
570 return new Integer(parseInt(name, value));
636 return parseInt(name, value);
571637 }
572638
573639 private int parseInt(String name, String value) throws SAXParseException {
590656 if (value == null) {
591657 return defaultValue;
592658 }
593 return new Long(parseLong(name, value));
659 return parseLong(name, value);
594660 }
595661
596662 private long parseLong(String name, String value) throws SAXParseException {
614680 if (value == null) {
615681 return defaultValue;
616682 }
617 return Boolean.valueOf(parseBoolean(name, value));
683 return parseBoolean(name, value);
618684 }
619685
620686 static final String TRUE = Boolean.TRUE.toString().toLowerCase(Locale.US);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 * Parses delimited string and returns an array containing the tokens. This parser obeys quotes,
2626 * so the delimiter character will be ignored if it is inside of a quote. This method assumes
2727 * that the quote character is not included in the set of delimiter characters.
28 *
28 *
2929 * @param value
3030 * the delimited string to parse.
3131 * @param delim
3838 value = "";
3939 }
4040
41 final List<String> list = new ArrayList<String>();
41 final List<String> list = new ArrayList<>();
4242
4343 final int CHAR = 1;
4444 final int DELIMITER = 2;
4545 final int STARTQUOTE = 4;
4646 final int ENDQUOTE = 8;
4747
48 final StringBuffer sb = new StringBuffer();
48 final StringBuilder sb = new StringBuilder();
4949
5050 int expecting = (CHAR | DELIMITER | STARTQUOTE);
5151
52 for (int i = 0; i < value.length(); i++) {
53 final char c = value.charAt(i);
54
52 for (final char c : value.toCharArray()) {
5553 final boolean isDelimiter = (delim.indexOf(c) >= 0);
5654 final boolean isQuote = (c == '"');
5755
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535
3636 private String input;
3737
38 private boolean splitted = false;
39
40 private boolean toString = false;
41
42 public Version(String versionStr, String qualifier) throws ParseException {
38 private volatile boolean split = false;
39
40 private volatile boolean toString = false;
41
42 public Version(String versionStr, String qualifier) {
4343 this(qualifier == null ? versionStr : (versionStr + "." + qualifier));
4444 }
4545
46 public Version(String versionStr) throws ParseException {
46 public Version(String versionStr) {
4747 this.input = versionStr;
48 splitted = false;
48 split = false;
4949 toString = false;
5050 }
5151
5454 this.minor = minor;
5555 this.patch = patch;
5656 this.qualifier = qualifier;
57 splitted = true;
57 split = true;
5858 toString = false;
5959 }
6060
6161 /**
6262 * Build a version from another one while appending an extra qualifier
63 *
63 *
6464 * @param baseVersion
65 * @param qualifier
65 * Version
66 * @param extraQualifier
67 * String
6668 */
6769 public Version(Version baseVersion, String extraQualifier) {
6870 this.major = baseVersion.major;
6971 this.minor = baseVersion.minor;
7072 this.patch = baseVersion.patch;
71 this.qualifier = baseVersion.qualifier == null ? extraQualifier
73 this.qualifier = (baseVersion.qualifier == null) ? extraQualifier
7274 : (baseVersion.qualifier + extraQualifier);
73 splitted = true;
75 split = true;
7476 toString = false;
7577 }
7678
77 private void ensureSplitted() {
78 if (!splitted) {
79 private void ensureSplit() {
80 if (!split) {
7981 synchronized (this) {
80 if (splitted) {
82 if (split) {
8183 return;
8284 }
8385 String[] splits = input.split("\\.");
8486 if (splits == null || splits.length == 0 || splits.length > 4) {
85 throw new RuntimeException(new ParseException("Ill formed OSGi version", 0));
87 throw new RuntimeException(new ParseException("Ill-formed OSGi version", 0));
8688 }
8789 try {
8890 major = Integer.parseInt(splits[0]);
103105 "Patch part of an OSGi version should be an integer", 0));
104106 }
105107 qualifier = splits.length == 4 ? splits[3] : null;
106 splitted = true;
108 split = true;
107109 }
108110 }
109111 }
114116 if (toString) {
115117 return;
116118 }
117 ensureSplitted();
119 ensureSplit();
118120 version = major + "." + minor + "." + patch
119121 + (qualifier == null ? "" : "." + qualifier);
120122 toString = true;
128130 }
129131
130132 public int hashCode() {
131 ensureSplitted();
133 ensureSplit();
132134 final int prime = 31;
133135 int result = 1;
134136 result = prime * result + major;
142144 if (this == obj) {
143145 return true;
144146 }
145 if (obj == null) {
147 if (obj == null || !(obj instanceof Version)) {
146148 return false;
147149 }
148 if (!(obj instanceof Version)) {
149 return false;
150 }
151150 Version other = (Version) obj;
152 ensureSplitted();
153 other.ensureSplitted();
154 if (major != other.major) {
155 return false;
156 }
157 if (minor != other.minor) {
158 return false;
159 }
160 if (patch != other.patch) {
161 return false;
162 }
163 if (qualifier == null) {
164 if (other.qualifier != null) {
165 return false;
166 }
167 } else if (!qualifier.equals(other.qualifier)) {
168 return false;
169 }
170 return true;
151 ensureSplit();
152 other.ensureSplit();
153 return major == other.major && minor == other.minor && patch == other.patch
154 && (qualifier == null ? other.qualifier == null : qualifier.equals(other.qualifier));
171155 }
172156
173157 public Version withNudgedPatch() {
174 ensureSplitted();
158 ensureSplit();
175159 return new Version(major, minor, patch + 1, null);
176160 }
177161
178162 public Version withoutQualifier() {
179 ensureSplitted();
163 ensureSplit();
180164 return new Version(major, minor, patch, null);
181165 }
182166
183167 public String qualifier() {
184 ensureSplitted();
185 return qualifier == null ? "" : qualifier;
168 ensureSplit();
169 return (qualifier == null) ? "" : qualifier;
186170 }
187171
188172 public int compareUnqualified(Version other) {
189 ensureSplitted();
190 other.ensureSplitted();
173 ensureSplit();
174 other.ensureSplit();
191175 int diff = major - other.major;
192176 if (diff != 0) {
193177 return diff;
204188 }
205189
206190 public int compareTo(Version other) {
207 ensureSplitted();
208 other.ensureSplitted();
191 ensureSplit();
192 other.ensureSplit();
209193 int diff = compareUnqualified(other);
210194 if (diff != 0) {
211195 return diff;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232
3333 public int compare(Version objA, Version objB) {
3434 final int val = objA.compareTo(objB);
35 return (reverse ? -val : val);
35 return reverse ? -val : val;
3636 }
3737
3838 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.text.ParseException;
2020
21 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
22
2123 /**
2224 * Provides version range support.
2325 */
3234 private Version endVersion;
3335
3436 public VersionRange(String versionStr) throws ParseException {
35 if (versionStr == null || versionStr.length() == 0) {
37 if (isNullOrEmpty(versionStr)) {
3638 startExclusive = false;
3739 startVersion = new Version(0, 0, 0, null);
3840 endExclusive = true;
6668
6769 /**
6870 * Default constructor
69 *
70 * @param header
71 * the header to parse
71 *
72 * @param version
73 * the version to parse
7274 */
7375 VersionRangeParser(String version) {
7476 this.version = version;
7779
7880 /**
7981 * Do the parsing
80 *
81 * @throws ParseException
82 *
83 * @throws ParseException if something goes wrong
8284 */
8385 void parse() throws ParseException {
8486 boolean range = parseStart();
146148 if (major == null) {
147149 return null;
148150 }
149 Integer minor = new Integer(0);
150 Integer patch = new Integer(0);
151 String qualififer = null;
151 Integer minor = 0;
152 Integer patch = 0;
153 String qualifier = null;
152154 if (parseNumberSeparator()) {
153155 minor = parseNumber();
154156 if (minor == null) {
155 minor = new Integer(0);
157 minor = 0;
156158 } else if (parseNumberSeparator()) {
157159 patch = parseNumber();
158160 if (patch == null) {
159 patch = new Integer(0);
161 patch = 0;
160162 } else if (parseNumberSeparator()) {
161 qualififer = parseQualifier();
163 qualifier = parseQualifier();
162164 }
163165 }
164166 }
165 return new Version(major.intValue(), minor.intValue(), patch.intValue(), qualififer);
167 return new Version(major, minor, patch, qualifier);
166168 }
167169
168170 private Integer parseNumber() {
182184 case '7':
183185 case '8':
184186 case '9':
185 n = new Integer((n == null ? 0 : n.intValue() * 10) + c - '0');
187 n = (n == null ? 0 : n * 10) + c - '0';
186188 break;
187189 default:
188190 unread();
214216 }
215217
216218 private String parseQualifier() {
217 StringBuffer q = new StringBuffer();
219 StringBuilder q = new StringBuilder();
218220 do {
219221 readNext();
220222 if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9'
242244 break;
243245 default:
244246 unread();
245 throw new ParseException("Expexting ] or )", pos);
247 throw new ParseException("Expecting ] or )", pos);
246248 }
247249 }
248250 }
263265 }
264266
265267 public String toString() {
266 return (startExclusive ? "(" : "[") + startVersion + ","
268 return (startExclusive ? "(" : "[") + startVersion.toString() + ","
267269 + (endVersion == null ? "" : endVersion.toString()) + (endExclusive ? ")" : "]");
268270 }
269271
270272 public String toIvyRevision() {
271 StringBuffer buffer = new StringBuffer();
272 buffer.append(startExclusive ? "(" : "[");
273 buffer.append(startVersion);
274 if (endVersion == null) {
275 buffer.append(",)");
276 } else if (!endExclusive || startVersion.equals(endVersion)) {
277 buffer.append(",");
278 buffer.append(endVersion.withNudgedPatch());
279 buffer.append(")");
280 } else {
281 buffer.append(",");
282 buffer.append(endVersion);
283 buffer.append(")");
284 }
285 return buffer.toString();
273 StringBuilder buffer = new StringBuilder();
274 buffer.append(startExclusive ? "(" : "[").append(startVersion).append(",");
275 if (endVersion != null) {
276 if (!endExclusive || startVersion.equals(endVersion)) {
277 buffer.append(endVersion.withNudgedPatch());
278 } else {
279 buffer.append(endVersion);
280 }
281 }
282 return buffer.append(")").toString();
286283 }
287284
288285 public boolean isEndExclusive() {
305302 return startVersion.equals(endVersion);
306303 }
307304
308 public boolean contains(String versionStr) throws ParseException {
305 public boolean contains(String versionStr) {
309306 return contains(new Version(versionStr));
310307 }
311308
312309 public boolean contains(Version version) {
313 if (startExclusive ? version.compareUnqualified(startVersion) <= 0 : version
314 .compareUnqualified(startVersion) < 0) {
315 return false;
316 }
317 if (endVersion == null) {
318 return true;
319 }
320 if (endExclusive ? version.compareUnqualified(endVersion) >= 0 : version
321 .compareUnqualified(endVersion) > 0) {
322 return false;
323 }
324 return true;
310 return (startExclusive ? version.compareUnqualified(startVersion) > 0 : version.compareUnqualified(startVersion) >= 0)
311 && (endVersion == null || (endExclusive ? version.compareUnqualified(endVersion) < 0 : version.compareUnqualified(endVersion) <= 0));
325312 }
326313
327314 public int hashCode() {
338325 if (this == obj) {
339326 return true;
340327 }
341 if (obj == null) {
342 return false;
343 }
344 if (!(obj instanceof VersionRange)) {
328 if (obj == null || !(obj instanceof VersionRange)) {
345329 return false;
346330 }
347331 VersionRange other = (VersionRange) obj;
355339 } else if (!endVersion.equals(other.endVersion)) {
356340 return false;
357341 }
358 if (startExclusive != other.startExclusive) {
359 return false;
360 }
361 if (startVersion == null) {
362 if (other.startVersion != null) {
363 return false;
364 }
365 } else if (!startVersion.equals(other.startVersion)) {
366 return false;
367 }
368 return true;
342 return startExclusive == other.startExclusive
343 && (startVersion == null ? other.startVersion == null : startVersion.equals(other.startVersion));
369344 }
370345
371346 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4242 private static void zipFiles(File rootDir, File currDir, ZipOutputStream zos)
4343 throws IOException {
4444 if (currDir.isDirectory()) {
45 final File[] files = currDir.listFiles();
46 for (int i = 0; i < files.length; i++) {
47 zipFiles(rootDir, files[i], zos);
45 for (File file : currDir.listFiles()) {
46 zipFiles(rootDir, file, zos);
4847 }
4948 } else {
5049 final String strAbsPath = currDir.getPath();
51 final String strZipEntryName = strAbsPath.substring(rootDir.getPath().length() + 1,
52 strAbsPath.length());
50 final String strZipEntryName = strAbsPath.substring(rootDir.getPath().length() + 1);
5351
5452 final byte[] b = new byte[(int) (currDir.length())];
5553 final FileInputStream fis = new FileInputStream(currDir);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3131 super(name);
3232 }
3333
34 private Collection/* <String> */circularDependencies = new HashSet();
34 private final Collection<String> circularDependencies = new HashSet<>();
3535
3636 public void handleCircularDependency(ModuleRevisionId[] mrids) {
3737 String circularDependencyId = getCircularDependencyId(mrids);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.plugins.circular;
1818
19 import java.util.Collection;
20
1921 import org.apache.ivy.core.module.id.ModuleRevisionId;
2022
2123 /**
2426
2527 public class CircularDependencyException extends RuntimeException {
2628
29 /**
30 *
31 */
32 private static final long serialVersionUID = 670272039106237360L;
33
2734 private ModuleRevisionId[] mrids;
2835
2936 /**
30 * @param descriptors
37 * @param mrids
3138 * module descriptors in order of circular dependency
3239 */
3340 public CircularDependencyException(final ModuleRevisionId[] mrids) {
3542 this.mrids = mrids;
3643 }
3744
45 public CircularDependencyException(final Collection<ModuleRevisionId> mrids) {
46 this(mrids.toArray(new ModuleRevisionId[mrids.size()]));
47 }
48
3849 public ModuleRevisionId[] getPath() {
3950 return this.mrids;
4051 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.plugins.circular;
1818
19 import java.util.Arrays;
1920 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.LinkedList;
2122 import java.util.List;
2223 import java.util.Set;
2324
2829
2930 /** CircularDependencyHelper is not designed to be an instance */
3031 private CircularDependencyHelper() {
31
3232 }
3333
3434 /**
3535 * Returns a string representation of this circular dependency graph
36 *
37 * @param descriptors
36 *
37 * @param mrids
3838 * in order of circular dependency
3939 * @return a string representation of this circular dependency graph
4040 */
4141 public static String formatMessage(final ModuleRevisionId[] mrids) {
42 Set alreadyAdded = new HashSet();
43 StringBuffer buff = new StringBuffer();
44 buff.append(mrids[0]);
45 alreadyAdded.add(mrids[0]);
46 for (int i = 1; i < mrids.length; i++) {
47 buff.append("->");
48 if (alreadyAdded.add(mrids[i])) {
49 buff.append(mrids[i]);
42 Set<ModuleRevisionId> alreadyAdded = new HashSet<>();
43 StringBuilder buff = new StringBuilder();
44 for (ModuleRevisionId mrid : mrids) {
45 if (buff.length() > 0) {
46 buff.append("->");
47 }
48 if (alreadyAdded.add(mrid)) {
49 buff.append(mrid);
5050 } else {
5151 buff.append("...");
5252 break;
5656 }
5757
5858 public static String formatMessage(final ModuleDescriptor[] descriptors) {
59 return formatMessage(toMrids(descriptors));
59 return formatMessageFromDescriptors(Arrays.asList(descriptors));
6060 }
6161
6262 /**
6363 * @param loopElements
64 * a List<ModuleDescriptor>
64 * a List&lt;ModuleDescriptor&gt;
65 * @return String
6566 */
66 public static String formatMessageFromDescriptors(List loopElements) {
67 ModuleRevisionId[] mrids = new ModuleRevisionId[loopElements.size()];
68 int pos = 0;
69 for (Iterator it = loopElements.iterator(); it.hasNext();) {
70 ModuleDescriptor descriptor = (ModuleDescriptor) it.next();
71 mrids[pos] = descriptor.getModuleRevisionId();
72 pos++;
67 public static String formatMessageFromDescriptors(List<ModuleDescriptor> loopElements) {
68 List<ModuleRevisionId> mrids = new LinkedList<>();
69 for (ModuleDescriptor descriptor : loopElements) {
70 mrids.add(descriptor.getModuleRevisionId());
7371 }
74 return formatMessage(mrids);
75 }
76
77 public static ModuleRevisionId[] toMrids(ModuleDescriptor[] descriptors) {
78 ModuleRevisionId[] mrids = new ModuleRevisionId[descriptors.length];
79 for (int i = 0; i < descriptors.length; i++) {
80 mrids[i] = descriptors[i].getModuleRevisionId();
81 }
82 return mrids;
72 return formatMessage(mrids.toArray(new ModuleRevisionId[mrids.size()]));
8373 }
8474
8575 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020
2121 /**
2222 * A CircularDependencyStrategy indicates what ivy does when a circular dependency is detected. Ivy
23 * can ignore it, warn the user, or interupt the processing.
23 * can ignore it, warn the user, or interrupt the processing.
2424 */
2525 public interface CircularDependencyStrategy {
2626 String getName();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.Collection;
2020
2121 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
22 import org.apache.ivy.core.module.id.ModuleRevisionId;
2223 import org.apache.ivy.core.settings.IvySettings;
2324 import org.apache.ivy.plugins.IvySettingsAware;
2425
4344 this.name = name;
4445 }
4546
47 @Override
4648 public String toString() {
4749 return name;
4850 }
4951
50 public void handleAllBlacklistedRevisions(DependencyDescriptor dd, Collection foundBlacklisted) {
52 public void handleAllBlacklistedRevisions(DependencyDescriptor dd,
53 Collection<ModuleRevisionId> foundBlacklisted) {
5154 }
5255 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.Collection;
2020
2121 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
22 import org.apache.ivy.core.module.id.ModuleRevisionId;
2223 import org.apache.ivy.core.resolve.IvyNode;
2324
2425 public interface ConflictManager {
2930 * this conflict manager is not able to resolve conflicts with the current data found in the
3031 * IvyNodes and need them to be fully loaded, it will return null to indicate that no conflict
3132 * resolution has been done.
32 *
33 *
3334 * @param parent
3435 * the ivy node parent for which the conflict is to be resolved
3536 * @param conflicts
3738 * @return a Collection of IvyNode which have not been evicted, or null if conflict management
3839 * resolution is not possible yet
3940 */
40 Collection resolveConflicts(IvyNode parent, Collection conflicts);
41 Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts);
4142
4243 String getName();
4344
4849 * This will never happen if the conflict manager doesn't blacklist any module, so providing an
4950 * empty implementation in this case is fine.
5051 * </p>
51 *
52 *
5253 * @param dd
5354 * the dependency descriptor for which all revisions are blacklisted.
5455 * @param foundBlacklisted
5556 * the list of all ModuleRevisionId found which are blacklisted
5657 */
5758 void handleAllBlacklistedRevisions(DependencyDescriptor dd,
58 Collection/* <ModuleRevisionId> */foundBlacklisted);
59 Collection<ModuleRevisionId> foundBlacklisted);
5960 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.ArrayList;
2020 import java.util.Arrays;
2121 import java.util.Collection;
22 import java.util.Iterator;
2322
2423 import org.apache.ivy.core.resolve.IvyNode;
2524
2625 public class FixedConflictManager extends AbstractConflictManager {
27 private Collection revisions;
26
27 private Collection<String> revisions;
2828
2929 public FixedConflictManager(String[] revs) {
3030 revisions = Arrays.asList(revs);
3131 setName("fixed" + revisions);
3232 }
3333
34 public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
35 Collection resolved = new ArrayList(conflicts.size());
36 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
37 IvyNode node = (IvyNode) iter.next();
34 public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
35 Collection<IvyNode> resolved = new ArrayList<>(conflicts.size());
36 for (IvyNode node : conflicts) {
3837 String revision = node.getResolvedId().getRevision();
3938 if (revisions.contains(revision)) {
4039 resolved.add(node);
4342 return resolved;
4443 }
4544
46 public Collection getRevs() {
45 public Collection<String> getRevs() {
4746 return revisions;
4847 }
4948
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4545 * set of compatible dependencies, even if it requires stepping back to older revisions (as long as
4646 * they are in the set of compatibility).
4747 * <p>
48 * Here is an example of what this conflict manager is able to do:<br/>
48 * Here is an example of what this conflict manager is able to do:
49 * </p>
4950 * <b>Available Modules</b>:
50 *
5151 * <pre>
5252 * #A;2-&gt;{ #B;[1.0,1.5] #C;[2.0,2.5] }
5353 * #B;1.4-&gt;#D;1.5
5454 * #B;1.5-&gt;#D;2.0
5555 * #C;2.5-&gt;#D;[1.0,1.6]
5656 * </pre>
57 *
58 * <b>Result</b>: #B;1.4, #C;2.5, #D;1.5<br/>
57 * <b>Result</b>: #B;1.4, #C;2.5, #D;1.5
58 * <p>
5959 * <b>Details</b>The conflict manager finds that the latest matching version of #B (1.5) depends on
6060 * a version of #D incompatible with what is expected by the latest matching version of #C. Hence
6161 * the conflict manager blacklists #B;1.5, and the version range [1.0,1.5] is resolved again to end
7070 super(name, strategy);
7171 }
7272
73 public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
73 @Override
74 public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
7475 if (conflicts.size() < 2) {
7576 return conflicts;
7677 }
7778 VersionMatcher versionMatcher = getSettings().getVersionMatcher();
7879
79 Iterator iter = conflicts.iterator();
80 IvyNode node = (IvyNode) iter.next();
80 Iterator<IvyNode> iter = conflicts.iterator();
81 IvyNode node = iter.next();
8182 ModuleRevisionId mrid = node.getResolvedId();
8283
8384 if (versionMatcher.isDynamic(mrid)) {
8485 while (iter.hasNext()) {
85 IvyNode other = (IvyNode) iter.next();
86 if (versionMatcher.isDynamic(other.getResolvedId())) {
86 IvyNode other = iter.next();
87 if (versionMatcher.isDynamic(other.getResolvedId())
88 || !versionMatcher.accept(mrid, other.getResolvedId())
89 && !handleIncompatibleConflict(parent, conflicts, node, other)) {
8790 // two dynamic versions in conflict, not enough information yet
91 // or incompatibility found
8892 return null;
89 } else if (!versionMatcher.accept(mrid, other.getResolvedId())) {
90 // incompatibility found
91 if (!handleIncompatibleConflict(parent, conflicts, node, other)) {
92 return null;
93 }
9493 }
9594 }
9695 // no incompatibility nor dynamic version found, let's return the latest static version
9796 if (conflicts.size() == 2) {
9897 // very common special case of only two modules in conflict,
9998 // let's return the second one (static)
100 Iterator it = conflicts.iterator();
99 Iterator<IvyNode> it = conflicts.iterator();
101100 it.next();
102101 return Collections.singleton(it.next());
103102 }
104 Collection newConflicts = new LinkedHashSet(conflicts);
103 Collection<IvyNode> newConflicts = new LinkedHashSet<>(conflicts);
105104 newConflicts.remove(node);
106105 return super.resolveConflicts(parent, newConflicts);
107106 } else {
108107 // the first node is a static revision, let's see if all other versions match
109108 while (iter.hasNext()) {
110 IvyNode other = (IvyNode) iter.next();
111 if (!versionMatcher.accept(other.getResolvedId(), mrid)) {
109 IvyNode other = iter.next();
110 if (!versionMatcher.accept(other.getResolvedId(), mrid)
111 && !handleIncompatibleConflict(parent, conflicts, node, other)) {
112112 // incompatibility found
113 if (!handleIncompatibleConflict(parent, conflicts, node, other)) {
114 return null;
115 }
113 return null;
116114 }
117115 }
118116 // no incompatibility found, let's return this static version
124122 * Handles an incompatible conflict
125123 * <p>
126124 * An incompatible conflicts is handled with this pseudo algorithm:
127 *
125 *
128126 * <pre>
129127 * take latest among two nodes in conflict
130128 * for all callers
137135 * else
138136 * throw strict conflict exception
139137 * </pre>
140 *
138 *
141139 * </p>
142 *
140 *
143141 * @param parent
144142 * the parent node of nodes in conflict
145143 * @param conflicts
151149 * @return true if the incompatible conflict has been handled, false otherwise (in which case
152150 * resolveConflicts should return null)
153151 */
154 private boolean handleIncompatibleConflict(IvyNode parent, Collection conflicts, IvyNode node,
155 IvyNode other) {
152 private boolean handleIncompatibleConflict(IvyNode parent, Collection<IvyNode> conflicts,
153 IvyNode node, IvyNode other) {
156154 // we never actually return anything else than false or throw an exception,
157155 // but returning a boolean make the calling code cleaner
158156 try {
159157 IvyNodeArtifactInfo latest = (IvyNodeArtifactInfo) getStrategy().findLatest(
160 toArtifactInfo(Arrays.asList(new IvyNode[] {node, other})), null);
158 toArtifactInfo(Arrays.asList(node, other)), null);
161159 if (latest != null) {
162160 IvyNode latestNode = latest.getNode();
163161 IvyNode oldestNode = latestNode == node ? other : node;
175173 return false;
176174 }
177175 } catch (NoConflictResolvedYetException ex) {
178 // we have not enough informations in the nodes to resolve conflict
176 // we have not enough information in the nodes to resolve conflict
179177 // according to the resolveConflicts contract, resolveConflicts must return null
180178 return false;
181179 }
183181
184182 private void blackListIncompatibleCallerAndRestartResolveIfPossible(IvySettings settings,
185183 IvyNode parent, IvyNode selected, IvyNode evicted) {
186 Stack callerStack = new Stack();
184 Stack<IvyNode> callerStack = new Stack<>();
187185 callerStack.push(evicted);
188 final Collection toBlacklist = blackListIncompatibleCaller(settings.getVersionMatcher(),
189 parent, selected, evicted, callerStack);
186 Collection<IvyNodeBlacklist> toBlacklist = blackListIncompatibleCaller(
187 settings.getVersionMatcher(), parent, selected, evicted, callerStack);
190188 if (toBlacklist != null) {
191 final StringBuffer blacklisted = new StringBuffer();
192 for (Iterator iterator = toBlacklist.iterator(); iterator.hasNext();) {
193 IvyNodeBlacklist blacklist = (IvyNodeBlacklist) iterator.next();
194 blacklist.getBlacklistedNode().blacklist(blacklist);
195 blacklisted.append(blacklist.getBlacklistedNode());
196 if (iterator.hasNext()) {
189 final StringBuilder blacklisted = new StringBuilder();
190 for (IvyNodeBlacklist blacklist : toBlacklist) {
191 if (blacklisted.length() > 0) {
197192 blacklisted.append(" ");
198193 }
194 IvyNode blacklistedNode = blacklist.getBlacklistedNode();
195 blacklistedNode.blacklist(blacklist);
196 blacklisted.append(blacklistedNode);
199197 }
200198
201199 String rootModuleConf = parent.getData().getReport().getConfiguration();
211209 }
212210 }
213211
214 private boolean handleIncompatibleCaller(Stack callerStack, IvyNode node, IvyNode callerNode,
215 IvyNode conflictParent, IvyNode selectedNode, IvyNode evictedNode,
216 Collection blacklisted, VersionMatcher versionMatcher) {
212 private boolean handleIncompatibleCaller(Stack<IvyNode> callerStack, IvyNode node,
213 IvyNode callerNode, IvyNode conflictParent, IvyNode selectedNode, IvyNode evictedNode,
214 Collection<IvyNodeBlacklist> blacklisted, VersionMatcher versionMatcher) {
217215 if (callerStack.subList(0, callerStack.size() - 1).contains(node)) {
218216 // circular dependency found and handled: the current top of the stack (node)
219217 // was already contained in the rest of the stack, the circle is closed, nothing
221219 return true;
222220 } else {
223221 callerStack.push(callerNode);
224 Collection sub = blackListIncompatibleCaller(versionMatcher, conflictParent,
225 selectedNode, evictedNode, callerStack);
222 Collection<IvyNodeBlacklist> sub = blackListIncompatibleCaller(versionMatcher,
223 conflictParent, selectedNode, evictedNode, callerStack);
226224 callerStack.pop();
227225 if (sub == null) {
228 // propagate the fact that a path with unblacklistable caller has been found
226 // propagate the fact that a path with nonblacklistable caller has been found
229227 return false;
230228 } else {
231229 blacklisted.addAll(sub);
236234
237235 /**
238236 * Tries to blacklist exactly one version for all callers paths.
239 *
237 *
240238 * @param versionMatcher
241239 * the version matcher to use to interpret versions
242240 * @param conflictParent
245243 * the node in favor of which the conflict is resolved
246244 * @param evictedNode
247245 * the node which will be evicted if we are able to blacklist all paths
248 * @param node
249 * the node for which callers should be considered
246 * @param callerStack
247 * ditto
250248 * @return the collection of blacklisting to do, null if a blacklist is not possible in at least
251249 * one caller path
252250 */
253 private Collection/* <IvyNodeBlacklist> */blackListIncompatibleCaller(
254 VersionMatcher versionMatcher, IvyNode conflictParent, IvyNode selectedNode,
255 IvyNode evictedNode, Stack/* <IvyNode> */callerStack) {
256 Collection/* <IvyNodeBlacklist> */blacklisted = new ArrayList/* <IvyNodeBlacklist> */();
257 IvyNode node = (IvyNode) callerStack.peek();
251 private Collection<IvyNodeBlacklist> blackListIncompatibleCaller(VersionMatcher versionMatcher,
252 IvyNode conflictParent, IvyNode selectedNode, IvyNode evictedNode,
253 Stack<IvyNode> callerStack) {
254 Collection<IvyNodeBlacklist> blacklisted = new ArrayList<>();
255 IvyNode node = callerStack.peek();
258256 String rootModuleConf = conflictParent.getData().getReport().getConfiguration();
259 Caller[] callers = node.getCallers(rootModuleConf);
260 for (int i = 0; i < callers.length; i++) {
261 IvyNode callerNode = node.findNode(callers[i].getModuleRevisionId());
257 for (Caller caller : node.getCallers(rootModuleConf)) {
258 IvyNode callerNode = node.findNode(caller.getModuleRevisionId());
262259 if (callerNode.isBlacklisted(rootModuleConf)) {
263260 continue;
264261 }
265 if (versionMatcher.isDynamic(callers[i].getAskedDependencyId(node.getData()))) {
262 if (versionMatcher.isDynamic(caller.getAskedDependencyId())) {
266263 blacklisted.add(new IvyNodeBlacklist(conflictParent, selectedNode, evictedNode,
267264 node, rootModuleConf));
268265 if (node.isEvicted(rootModuleConf)
281278 return blacklisted;
282279 }
283280
284 protected void handleUnsolvableConflict(IvyNode parent, Collection conflicts, IvyNode node1,
285 IvyNode node2) {
281 protected void handleUnsolvableConflict(IvyNode parent, Collection<IvyNode> conflicts,
282 IvyNode node1, IvyNode node2) {
286283 throw new StrictConflictException(node1, node2);
287284 }
288285
286 @Override
289287 public void handleAllBlacklistedRevisions(DependencyDescriptor dd,
290 Collection/* <ModuleRevisionId> */foundBlacklisted) {
288 Collection<ModuleRevisionId> foundBlacklisted) {
291289 ResolveData resolveData = IvyContext.getContext().getResolveData();
292 Collection/* <IvyNode> */blacklisted = new HashSet();
293 for (Iterator iterator = foundBlacklisted.iterator(); iterator.hasNext();) {
294 ModuleRevisionId mrid = (ModuleRevisionId) iterator.next();
290 Collection<IvyNode> blacklisted = new HashSet<>();
291 for (ModuleRevisionId mrid : foundBlacklisted) {
295292 blacklisted.add(resolveData.getNode(mrid));
296293 }
297294
298 for (Iterator iterator = blacklisted.iterator(); iterator.hasNext();) {
299 IvyNode node = (IvyNode) iterator.next();
295 for (IvyNode node : blacklisted) {
300296 IvyNodeBlacklist bdata = node.getBlacklistData(resolveData.getReport()
301297 .getConfiguration());
302298 handleUnsolvableConflict(bdata.getConflictParent(),
303 Arrays.asList(new Object[] {bdata.getEvictedNode(), bdata.getSelectedNode()}),
299 Arrays.asList(bdata.getEvictedNode(), bdata.getSelectedNode()),
304300 bdata.getEvictedNode(), bdata.getSelectedNode());
305301 }
306302 }
307303
304 @Override
308305 public String toString() {
309306 return getName();
310307 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.ArrayList;
2020 import java.util.Collection;
2121 import java.util.Collections;
22 import java.util.Iterator;
2322 import java.util.List;
2423
2524 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3029 import org.apache.ivy.util.Message;
3130
3231 public class LatestConflictManager extends AbstractConflictManager {
32 @SuppressWarnings("serial")
3333 public static class NoConflictResolvedYetException extends RuntimeException {
3434 }
3535
4444 long lastModified = node.getLastModified();
4545 if (lastModified == 0) {
4646 // if the last modified timestamp is unknown, we can't resolve
47 // the conflicts now, and trigger an exception which will be catched
47 // the conflicts now, and trigger an exception which will be caught
4848 // in the main resolveConflicts method
4949 throw new NoConflictResolvedYetException();
5050 } else {
7777 this.strategy = strategy;
7878 }
7979
80 public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
80 public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
8181 if (conflicts.size() < 2) {
8282 return conflicts;
8383 }
84 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
85 IvyNode node = (IvyNode) iter.next();
84 for (IvyNode node : conflicts) {
8685 DependencyDescriptor dd = node.getDependencyDescriptor(parent);
8786 if (dd != null && dd.isForce()
8887 && parent.getResolvedId().equals(dd.getParentRevisionId())) {
9493 * If the list of conflicts contains dynamic revisions, delay the conflict calculation until
9594 * they are resolved. TODO: we probably could already evict some of the dynamic revisions!
9695 */
97 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
98 IvyNode node = (IvyNode) iter.next();
96 for (IvyNode node : conflicts) {
9997 ModuleRevisionId modRev = node.getResolvedId();
10098 if (getSettings().getVersionMatcher().isDynamic(modRev)) {
10199 return null;
102100 }
103101 }
104102
105 ArrayList unevicted = new ArrayList();
106 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
107 IvyNode node = (IvyNode) iter.next();
108 if (!node.isCompletelyEvicted())
103 List<IvyNode> unevicted = new ArrayList<>();
104 for (IvyNode node : conflicts) {
105 if (!node.isCompletelyEvicted()) {
109106 unevicted.add(node);
107 }
110108 }
111109 if (unevicted.size() > 0) {
112110 conflicts = unevicted;
121119 return conflicts;
122120 }
123121 } catch (NoConflictResolvedYetException ex) {
124 // we have not enough informations in the nodes to resolve conflict
122 // we have not enough information in the nodes to resolve conflict
125123 // according to the resolveConflicts contract, we must return null
126124 return null;
127125 }
128126 }
129127
130 protected ArtifactInfo[] toArtifactInfo(Collection conflicts) {
131 List artifacts = new ArrayList(conflicts.size());
132 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
133 IvyNode node = (IvyNode) iter.next();
128 protected ArtifactInfo[] toArtifactInfo(Collection<IvyNode> conflicts) {
129 List<ArtifactInfo> artifacts = new ArrayList<>(conflicts.size());
130 for (IvyNode node : conflicts) {
134131 artifacts.add(new IvyNodeArtifactInfo(node));
135132 }
136 return (ArtifactInfo[]) artifacts.toArray(new ArtifactInfo[artifacts.size()]);
133 return artifacts.toArray(new ArtifactInfo[artifacts.size()]);
137134 }
138135
139136 public LatestStrategy getStrategy() {
153150
154151 /**
155152 * To conform to configurator API
156 *
157 * @param latestStrategy
153 *
154 * @param strategyName ditto
158155 */
159156 public void setLatest(String strategyName) {
160157 this.strategyName = strategyName;
164161 this.strategy = strategy;
165162 }
166163
164 @Override
167165 public String toString() {
168166 return strategy != null ? String.valueOf(strategy) : strategyName;
169167 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 setName("all");
2626 }
2727
28 public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
28 public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
2929 return conflicts;
3030 }
3131 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.Arrays;
2020 import java.util.Collection;
2121 import java.util.Collections;
22 import java.util.Iterator;
2322 import java.util.regex.Matcher;
2423 import java.util.regex.Pattern;
2524
2928 /**
3029 * A ConflictManager that can be used to resolve conflicts based on regular expressions of the
3130 * revision of the module. The conflict manager is added like this:
32 *
31 *
3332 * <pre>
3433 * &lt;!-- Match all revisions, but ignore the last dot(.) and the character after it.
3534 * Used to match api changes in out milestones. --&gt;
3635 * &lt;conflict-managers&gt;
37 * &lt;regexp-cm name=&quot;regexp&quot;
36 * &lt;regexp-cm name=&quot;regexp&quot;
3837 * regexp=&quot;(.*)\..$&quot; ignoreNonMatching=&quot;true&quot;/&gt;
3938 * &lt;/conflict-managers&gt;
4039 * </pre>
41 *
40 *
4241 * The regular expression must contain a capturing group. The group will be used to resolve the
4342 * conflicts by an String.equals() test. If ignoreNonMatching is false non matching modules will
44 * result in an exception. If it is true they will be compaired by their full revision.
43 * result in an exception. If it is true they will be compared by their full revision.
4544 */
4645 public class RegexpConflictManager extends AbstractConflictManager {
4746 private Pattern pattern = Pattern.compile("(.*)");
6564 mIgnoreNonMatching = ignoreNonMatching;
6665 }
6766
68 public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
67 public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
6968 IvyNode lastNode = null;
70 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
71 IvyNode node = (IvyNode) iter.next();
69 for (IvyNode node : conflicts) {
7270
7371 if (lastNode != null && !matchEquals(node, lastNode)) {
7472 String msg = lastNode + ":" + getMatch(lastNode) + " (needed by "
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import org.apache.ivy.core.resolve.IvyNode;
2222 import org.apache.ivy.core.resolve.ResolveProcessException;
2323
24 @SuppressWarnings("serial")
2425 public class StrictConflictException extends ResolveProcessException {
2526
2627 public StrictConflictException() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.Collection;
2020 import java.util.Collections;
21 import java.util.Iterator;
2221
2322 import org.apache.ivy.core.resolve.IvyNode;
2423 import org.apache.ivy.plugins.version.VersionMatcher;
2827 public StrictConflictManager() {
2928 }
3029
31 public Collection resolveConflicts(IvyNode parent, Collection conflicts) {
30 public Collection<IvyNode> resolveConflicts(IvyNode parent, Collection<IvyNode> conflicts) {
3231 VersionMatcher versionMatcher = getSettings().getVersionMatcher();
3332
3433 IvyNode lastNode = null;
35 for (Iterator iter = conflicts.iterator(); iter.hasNext();) {
36 IvyNode node = (IvyNode) iter.next();
37
34 for (IvyNode node : conflicts) {
3835 if (versionMatcher.isDynamic(node.getResolvedId())) {
3936 // dynamic revision, not enough information to resolve conflict
4037 return null;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3131 this.name = name;
3232 }
3333
34 @Override
3435 public String toString() {
3536 return name;
3637 }
3738
3839 public ArtifactInfo findLatest(ArtifactInfo[] infos, Date date) {
39 List l = sort(infos);
40 List<ArtifactInfo> l = sort(infos);
4041
4142 // the latest revision comes last, use a ListIterator to iterate the
4243 // sorted list in the reverse direction.
43 for (ListIterator iter = l.listIterator(l.size()); iter.hasPrevious();) {
44 ArtifactInfo info = (ArtifactInfo) iter.previous();
44 ListIterator<ArtifactInfo> iter = l.listIterator(l.size());
45 while (iter.hasPrevious()) {
46 ArtifactInfo info = iter.previous();
4547 if (date == null || info.getLastModified() < date.getTime()) {
4648 return info;
4749 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424
2525 public class ComparatorLatestStrategy extends AbstractLatestStrategy {
2626
27 private Comparator comparator;
27 private Comparator<ArtifactInfo> comparator;
2828
2929 public ComparatorLatestStrategy() {
3030 }
3131
32 public ComparatorLatestStrategy(Comparator comparator) {
32 public ComparatorLatestStrategy(Comparator<ArtifactInfo> comparator) {
3333 this.comparator = comparator;
3434 }
3535
36 public List sort(ArtifactInfo[] infos) {
37 List ret = new ArrayList(Arrays.asList(infos));
36 public List<ArtifactInfo> sort(ArtifactInfo[] infos) {
37 List<ArtifactInfo> ret = new ArrayList<>(Arrays.asList(infos));
3838 Collections.sort(ret, comparator);
3939 return ret;
4040 }
4141
42 public Comparator getComparator() {
42 public Comparator<ArtifactInfo> getComparator() {
4343 return comparator;
4444 }
4545
46 public void setComparator(Comparator comparator) {
46 public void setComparator(Comparator<ArtifactInfo> comparator) {
4747 this.comparator = comparator;
4848 }
4949
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 * assumed to be the greater. If a partial latest is found, then it is assumed to be greater
2626 * than any matching fixed revision.
2727 */
28 private static final Comparator COMPARATOR = new Comparator() {
29 public int compare(Object o1, Object o2) {
30 String rev1 = ((ArtifactInfo) o1).getRevision();
31 String rev2 = ((ArtifactInfo) o2).getRevision();
28 private static final Comparator<ArtifactInfo> COMPARATOR = new Comparator<ArtifactInfo>() {
29 public int compare(ArtifactInfo o1, ArtifactInfo o2) {
30 String rev1 = o1.getRevision();
31 String rev2 = o2.getRevision();
3232 if (rev1.startsWith("latest")) {
3333 return 1;
3434 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030 * Compares two ModuleRevisionId by their revision. Revisions are compared using an algorithm
3131 * inspired by PHP version_compare one.
3232 */
33 final class MridComparator implements Comparator {
34 public int compare(Object o1, Object o2) {
35 String rev1 = ((ModuleRevisionId) o1).getRevision();
36 String rev2 = ((ModuleRevisionId) o2).getRevision();
33 final class MridComparator implements Comparator<ModuleRevisionId> {
34 public int compare(ModuleRevisionId o1, ModuleRevisionId o2) {
35 String rev1 = o1.getRevision();
36 String rev2 = o2.getRevision();
3737
3838 rev1 = rev1.replaceAll("([a-zA-Z])(\\d)", "$1.$2");
3939 rev1 = rev1.replaceAll("(\\d)([a-zA-Z])", "$1.$2");
6060 return Long.valueOf(parts1[i]).compareTo(Long.valueOf(parts2[i]));
6161 }
6262 // both are strings, we compare them taking into account special meaning
63 Map specialMeanings = getSpecialMeanings();
64 Integer sm1 = (Integer) specialMeanings.get(parts1[i].toLowerCase(Locale.US));
65 Integer sm2 = (Integer) specialMeanings.get(parts2[i].toLowerCase(Locale.US));
63 Map<String, Integer> specialMeanings = getSpecialMeanings();
64 Integer sm1 = specialMeanings.get(parts1[i].toLowerCase(Locale.US));
65 Integer sm2 = specialMeanings.get(parts2[i].toLowerCase(Locale.US));
6666 if (sm1 != null) {
67 sm2 = sm2 == null ? new Integer(0) : sm2;
67 if (sm2 == null) {
68 sm2 = new Integer(0);
69 }
6870 return sm1.compareTo(sm2);
6971 }
7072 if (sm2 != null) {
9193 * inspired by PHP version_compare one, unless a dynamic revision is given, in which case the
9294 * version matcher is used to perform the comparison.
9395 */
94 final class ArtifactInfoComparator implements Comparator {
95 public int compare(Object o1, Object o2) {
96 String rev1 = ((ArtifactInfo) o1).getRevision();
97 String rev2 = ((ArtifactInfo) o2).getRevision();
96 final class ArtifactInfoComparator implements Comparator<ArtifactInfo> {
97 public int compare(ArtifactInfo o1, ArtifactInfo o2) {
98 String rev1 = o1.getRevision();
99 String rev2 = o2.getRevision();
98100
99101 /*
100102 * The revisions can still be not resolved, so we use the current version matcher to
151153 }
152154 }
153155
154 private static final Map DEFAULT_SPECIAL_MEANINGS;
156 private static final Map<String, Integer> DEFAULT_SPECIAL_MEANINGS;
155157 static {
156 DEFAULT_SPECIAL_MEANINGS = new HashMap();
157 DEFAULT_SPECIAL_MEANINGS.put("dev", new Integer(-1));
158 DEFAULT_SPECIAL_MEANINGS.put("rc", new Integer(1));
159 DEFAULT_SPECIAL_MEANINGS.put("final", new Integer(2));
160 }
161
162 private final Comparator mridComparator = new MridComparator();
163
164 private final Comparator artifactInfoComparator = new ArtifactInfoComparator();
165
166 private Map specialMeanings = null;
158 DEFAULT_SPECIAL_MEANINGS = new HashMap<>();
159 DEFAULT_SPECIAL_MEANINGS.put("dev", -1);
160 DEFAULT_SPECIAL_MEANINGS.put("rc", 1);
161 DEFAULT_SPECIAL_MEANINGS.put("final", 2);
162 }
163
164 private final Comparator<ModuleRevisionId> mridComparator = new MridComparator();
165
166 private final Comparator<ArtifactInfo> artifactInfoComparator = new ArtifactInfoComparator();
167
168 private Map<String, Integer> specialMeanings = null;
167169
168170 private boolean usedefaultspecialmeanings = true;
169171
177179 getSpecialMeanings().put(meaning.getName().toLowerCase(Locale.US), meaning.getValue());
178180 }
179181
180 public synchronized Map getSpecialMeanings() {
182 public synchronized Map<String, Integer> getSpecialMeanings() {
181183 if (specialMeanings == null) {
182 specialMeanings = new HashMap();
184 specialMeanings = new HashMap<>();
183185 if (isUsedefaultspecialmeanings()) {
184186 specialMeanings.putAll(DEFAULT_SPECIAL_MEANINGS);
185187 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 * Finds the latest artifact among the given artifacts info. The definition of 'latest' depends
2525 * on the strategy itself. Given artifacts info are all good candidate. If the given date is not
2626 * null, then found artifact should not be later than this date.
27 *
28 * @param infos
29 * @param date
27 *
28 * @param infos ArtifactInfo[]
29 * @param date Date
3030 * @return the latest artifact among the given ones.
3131 */
3232 ArtifactInfo findLatest(ArtifactInfo[] infos, Date date);
3434 /**
3535 * Sorts the given artifacts info from the oldest one to the latest one. The definition of
3636 * 'latest' depends on the strategy itself. Given artifacts info are all good candidate.
37 *
38 * @param infos
39 * @return
37 *
38 * @param infos ArtifactInfo[]
39 * @return List&lt;ArtifactInfo&gt;
4040 */
41 List sort(ArtifactInfo[] infos);
41 List<ArtifactInfo> sort(ArtifactInfo[] infos);
4242
4343 String getName();
4444 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.util.Comparator;
2020
2121 public class LatestTimeStrategy extends ComparatorLatestStrategy {
22 private static final Comparator COMPARATOR = new Comparator() {
23 public int compare(Object o1, Object o2) {
24 long d1 = ((ArtifactInfo) o1).getLastModified();
25 long d2 = ((ArtifactInfo) o2).getLastModified();
26 return new Long(d1).compareTo(new Long(d2));
22 private static final Comparator<ArtifactInfo> COMPARATOR = new Comparator<ArtifactInfo>() {
23 public int compare(ArtifactInfo o1, ArtifactInfo o2) {
24 return Long.compare(o1.getLastModified(), o2.getLastModified());
2725 }
2826
2927 };
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.plugins.latest;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 /**
23 * A strategy which delegate to another strategy, unless for the latest and working revisions which
24 * are considered as superior to any other revision.
25 * <p>NB : it is for internal usage of Ivy only!</p>
26 */
27 public class WorkspaceLatestStrategy extends AbstractLatestStrategy {
28
29 private LatestStrategy delegate;
30
31 public WorkspaceLatestStrategy(LatestStrategy delegate) {
32 this.delegate = delegate;
33 setName("workspace-" + delegate.getName());
34 }
35
36 public List<ArtifactInfo> sort(ArtifactInfo[] infos) {
37 List<ArtifactInfo> head = new ArrayList<>();
38 List<ArtifactInfo> tail = new ArrayList<>();
39
40 for (ArtifactInfo ai : delegate.sort(infos)) {
41 String rev = ai.getRevision();
42 boolean latestRev = rev.startsWith("latest") || rev.startsWith("working");
43 if (latestRev) {
44 head.add(ai);
45 } else {
46 tail.add(ai);
47 }
48 }
49
50 head.addAll(tail);
51 return head;
52 }
53
54 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.util.Iterator;
2121 import java.util.LinkedHashSet;
22 import java.util.Set;
2223
23 class DeleteOnExitHook {
24 final class DeleteOnExitHook {
2425
2526 static {
2627 Runtime.getRuntime().addShutdownHook(new Thread() {
3031 });
3132 }
3233
33 private static LinkedHashSet files = new LinkedHashSet();
34 private static final Set<File> files = new LinkedHashSet<>();
3435
3536 private DeleteOnExitHook() {
3637 }
4445 }
4546
4647 static synchronized void runHook() {
47 Iterator itr = files.iterator();
48 Iterator<File> itr = files.iterator();
4849 while (itr.hasNext()) {
49 ((File) itr.next()).delete();
50 itr.next().delete();
5051 itr.remove();
5152 }
5253 }
53 }
54 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.io.IOException;
2121 import java.io.RandomAccessFile;
2222 import java.nio.channels.FileLock;
23 import java.util.Enumeration;
24 import java.util.Map;
2523 import java.util.concurrent.ConcurrentHashMap;
2624 import java.util.concurrent.ConcurrentMap;
2725
4341 * Lock counter list must be static: locks are implicitly shared to the entire process, so the
4442 * list too much be.
4543 */
46 private static ConcurrentMap/* <File, Map<Thread, Integer>> */currentLockHolders = new ConcurrentHashMap();
44 private static final ConcurrentMap<File, ConcurrentMap<Thread, Integer>> currentLockHolders = new ConcurrentHashMap<>();
4745
4846 protected FileBasedLockStrategy() {
4947 this(new CreateFileLocker(false), false);
138136
139137 /**
140138 * Determine the state of the lockfile.
141 *
139 *
142140 * Must be called from within a synchronized block.
143 *
141 *
144142 * Three possibilities exist: - The lock is held by the current thread (>0) - The lock is held
145143 * by one or more different threads (-1) - The lock is not held at all (0).
146 *
144 *
147145 * @param file
148146 * file to lock
149147 * @param forThread
150148 * thread for which lock status is being queried
151149 */
152150 private int hasLock(File file, Thread forThread) {
153 Map locksPerThread = (Map) currentLockHolders.get(file);
151 ConcurrentMap<Thread, Integer> locksPerThread = currentLockHolders.get(file);
154152 if (locksPerThread == null) {
155153 return 0;
156154 }
157155 if (locksPerThread.isEmpty()) {
158156 return 0;
159157 }
160 Integer counterObj = (Integer) locksPerThread.get(forThread);
161 int counter = counterObj == null ? 0 : counterObj.intValue();
158 Integer counterObj = locksPerThread.get(forThread);
159 int counter = (counterObj == null) ? 0 : counterObj;
162160 if (counter > 0) {
163161 return counter;
164162 } else {
168166
169167 /**
170168 * Record that this thread holds the lock.
171 *
169 *
172170 * Asserts that the lock has been previously grabbed by this thread. Must be called from a
173171 * synchronized block in which the lock was grabbed.
174 *
172 *
175173 * @param file
176174 * file which has been locked
177175 * @param forThread
179177 * @return number of times this thread has grabbed the lock
180178 */
181179 private int incrementLock(File file, Thread forThread) {
182 Map locksPerThread = (Map) currentLockHolders.get(file);
180 ConcurrentMap<Thread, Integer> locksPerThread = currentLockHolders.get(file);
183181 if (locksPerThread == null) {
184 locksPerThread = new ConcurrentHashMap();
182 locksPerThread = new ConcurrentHashMap<>();
185183 currentLockHolders.put(file, locksPerThread);
186184 }
187 Integer c = (Integer) locksPerThread.get(forThread);
188 int holdLocks = c == null ? 1 : c.intValue() + 1;
189 locksPerThread.put(forThread, new Integer(holdLocks));
185 Integer c = locksPerThread.get(forThread);
186 int holdLocks = (c == null) ? 1 : c + 1;
187 locksPerThread.put(forThread, holdLocks);
190188 return holdLocks;
191189 }
192190
193191 /**
194192 * Decrease depth of this thread's lock.
195 *
193 *
196194 * Must be called within a synchronized block.
197 *
195 *
198196 * If this returns 0, the caller is responsible for releasing the lock within that same block.
199 *
197 *
200198 * @param file
201199 * file for which lock depth is being decreased
202200 * @param forThread
204202 * @return remaining depth of this lock
205203 */
206204 private int decrementLock(File file, Thread forThread) {
207 ConcurrentHashMap locksPerThread = (ConcurrentHashMap) currentLockHolders.get(file);
205 ConcurrentMap<Thread, Integer> locksPerThread = currentLockHolders.get(file);
208206 if (locksPerThread == null) {
209207 throw new RuntimeException("Calling decrementLock on a thread which holds no locks");
210208 }
211 Integer c = (Integer) locksPerThread.get(forThread);
212 int oldHeldLocks = c == null ? 0 : c.intValue();
209 Integer c = locksPerThread.get(forThread);
210 int oldHeldLocks = (c == null) ? 0 : c;
213211 if (oldHeldLocks <= 0) {
214212 throw new RuntimeException("Calling decrementLock on a thread which holds no locks");
215213 }
216214 int newHeldLocks = oldHeldLocks - 1;
217215 if (newHeldLocks > 0) {
218 locksPerThread.put(forThread, new Integer(newHeldLocks));
216 locksPerThread.put(forThread, newHeldLocks);
219217 } else {
220218 locksPerThread.remove(forThread);
221219 }
224222
225223 /**
226224 * Return a string naming the threads which currently hold this lock.
225 *
226 * @param file File
227 * @return String
227228 */
228229 protected String getCurrentLockHolderNames(File file) {
229230 StringBuilder sb = new StringBuilder();
230 ConcurrentHashMap m = (ConcurrentHashMap) currentLockHolders.get(file);
231 ConcurrentMap<Thread, Integer> m = currentLockHolders.get(file);
231232 if (m == null) {
232233 return "(NULL)";
233234 }
234 Enumeration threads = m.keys();
235 while (threads.hasMoreElements()) {
236 Thread t = (Thread) threads.nextElement();
235 for (Thread t : m.keySet()) {
236 if (sb.length() > 0) {
237 sb.append(", ");
238 }
237239 sb.append(t.toString());
238 if (threads.hasMoreElements()) {
239 sb.append(", ");
240 }
241240 }
242241 return sb.toString();
243242 }
244243
245 public static interface FileLocker {
244 public interface FileLocker {
246245 boolean tryLock(File f);
247246
248247 void unlock(File f);
290289 */
291290 public static class NIOFileLocker implements FileLocker {
292291
293 private Map locks = new ConcurrentHashMap();
292 private ConcurrentMap<File, LockData> locks = new ConcurrentHashMap<>();
294293
295294 private boolean debugLocking;
296295
309308 }
310309 }
311310
311 @SuppressWarnings("resource")
312312 public boolean tryLock(File file) {
313313 try {
314314 if (file.getParentFile().exists() || file.getParentFile().mkdirs()) {
336336
337337 public void unlock(File file) {
338338 synchronized (this) {
339 LockData data = (LockData) locks.get(file);
339 LockData data = locks.get(file);
340340 if (data == null) {
341341 throw new IllegalArgumentException("file not previously locked: " + file);
342342 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727 * Note that some implementations may actually choose to NOT perform locking, when no lock is
2828 * necessary (cache not shared). Some other implementations may choose to lock the cache for the
2929 * download of a whole module (not possible yet), or at the artifact level.
30 * </p>
3031 * <p>
32 * The lock methods should return true when the lock is either actually acquired or not performed by
33 * the strategy.
3134 * </p>
32 * The lock methods should return true when the lock is either actually acquired or not performed by
33 * the strategy. </p>
3435 * <p>
3536 * Locking used in the locking strategy must support reentrant lock. Reentrant locking should be
3637 * performed for the whole strategy.
4041
4142 /**
4243 * Returns the name of the strategy
43 *
44 *
4445 * @return the name of the strategy
4546 */
4647 String getName();
4748
4849 /**
4950 * Performs a lock before downloading the given {@link Artifact} to the given file.
50 *
51 *
5152 * @param artifact
5253 * the artifact about to be downloaded
5354 * @param artifactFileToDownload
6162
6263 /**
6364 * Release the lock acquired for an artifact download.
64 *
65 *
6566 * @param artifact
6667 * the artifact for which the lock was acquired
6768 * @param artifactFileToDownload
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525
2626 /**
2727 * Create a new instance of a pattern matcher
28 *
28 *
2929 * @param name
3030 * the name of the pattern matcher. Never null.
3131 */
4949
5050 /**
5151 * Returns an instance of the implementation specific matcher.
52 *
52 *
5353 * @param expression
5454 * the string to be matched.
5555 * @return the instance of the related matcher. Never null.
5656 */
5757 protected abstract/* @NotNull */Matcher newMatcher(/* @NotNull */String expression);
5858
59 @Override
5960 public String toString() {
6061 return getName();
6162 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 /**
2020 * A pattern matcher that tries to match exactly the input with the expression, or match it as a
2121 * pattern.
22 * <p/>
22 * <p>
2323 * The evaluation for matching is perform first by checking if expression and input are equals (via
2424 * equals method) else it attempts to do it by trying to match the input using the expression as a
2525 * regexp.
26 *
26 * </p>
27 *
2728 * @see ExactPatternMatcher
2829 * @see RegexpPatternMatcher
2930 */
3536 super(EXACT_OR_REGEXP);
3637 }
3738
39 @Override
3840 protected Matcher newMatcher(String expression) {
3941 return new ExactOrRegexpMatcher(expression);
4042 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 /**
2020 * Implementation of an exact matcher.
21 * <p/>
21 * <p>
2222 * The matching will be performed against an expression being a string. It will only matches if both
2323 * strings are equal (per equals()) rule or if both strings are null.
24 * </p>
2425 */
2526 public/* @Immutable */final class ExactPatternMatcher extends AbstractPatternMatcher {
2627
3031 super(EXACT);
3132 }
3233
34 @Override
3335 protected Matcher newMatcher(String expression) {
3436 return new ExactMatcher(expression);
3537 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 * <li>* - Matches zero or more characters</li>
3030 * <li>? - Matches exactly one character.</li>
3131 * </ul>
32 * <p/>
33 * <b> Note that this matcher is available only with <a href="http://jakarta.apache.org/oro"Apache
34 * Jakarta Oro 2.0.8</a> in your classpath.</b>
35 *
36 * @see <a
37 * href="http://jakarta.apache.org/oro/api/org/apache/oro/text/GlobCompiler.html">GlobCompiler</a>
32 * <p>
33 * NOTE: this matcher is available only with
34 * <a href="https://jakarta.apache.org/oro">Apache Jakarta ORO 2.0.8</a>
35 * in your classpath.
36 * </p>
37 *
38 * @see <a href="https://jakarta.apache.org/oro/api/org/apache/oro/text/GlobCompiler.html">GlobCompiler</a>
3839 */
3940 public/* @Immutable */final class GlobPatternMatcher extends AbstractPatternMatcher {
4041
5051 super(GLOB);
5152 }
5253
54 @Override
5355 protected Matcher newMatcher(String expression) {
5456 return new GlobMatcher(expression);
5557 }
8183 if (exact == null) {
8284 exact = calculateExact();
8385 }
84 return exact.booleanValue();
86 return exact;
8587 }
8688
8789 private Boolean calculateExact() {
8890 Boolean result = Boolean.TRUE;
8991
90 char[] expressionChars = expression.toCharArray();
91 for (int i = 0; i < expressionChars.length; i++) {
92 char ch = expressionChars[i];
92 for (char ch : expression.toCharArray()) {
9393 if (ch == '*' || ch == '?' || ch == '[' || ch == ']') {
9494 result = Boolean.FALSE;
9595 break;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.Collections;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.Map;
23 import java.util.Map.Entry;
2422
2523 public class MapMatcher {
26 private Map/* <String, Matcher> */matchers = new HashMap();
24 private Map<String, Matcher> matchers = new HashMap<>();
2725
2826 private PatternMatcher pm;
2927
30 private Map attributes;
28 private Map<String, String> attributes;
3129
32 public MapMatcher(Map attributes, PatternMatcher pm) {
30 public MapMatcher(Map<String, String> attributes, PatternMatcher pm) {
3331 this.attributes = attributes;
3432 this.pm = pm;
35 for (Iterator iter = attributes.entrySet().iterator(); iter.hasNext();) {
36 Entry entry = (Entry) iter.next();
37 String value = (String) entry.getValue();
33 for (Map.Entry<String, String> entry : attributes.entrySet()) {
34 String value = entry.getValue();
3835 if (value != null) {
3936 matchers.put(entry.getKey(), pm.getMatcher(value));
4037 }
4138 }
4239 }
4340
44 public boolean matches(Map/* <String,String> */m) {
45 for (Iterator iter = matchers.entrySet().iterator(); iter.hasNext();) {
46 Entry entry = (Entry) iter.next();
47
48 Matcher matcher = (Matcher) entry.getValue();
49 String value = (String) m.get(entry.getKey());
50 if ((value == null) || !matcher.matches(value)) {
41 public boolean matches(Map<String, String> m) {
42 for (Map.Entry<String, Matcher> entry : matchers.entrySet()) {
43 Matcher matcher = entry.getValue();
44 String value = m.get(entry.getKey());
45 if (value == null || !matcher.matches(value)) {
5146 return false;
5247 }
5348 }
5550 return true;
5651 }
5752
53 @Override
5854 public String toString() {
5955 return attributes + " (" + pm.getName() + ")";
6056 }
6157
62 public Map getAttributes() {
58 public Map<String, String> getAttributes() {
6359 return Collections.unmodifiableMap(attributes);
6460 }
6561
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323
2424 /**
2525 * Check whether a given string is matched by this matcher.
26 *
26 *
2727 * @param input
2828 * the string to be matched. Cannot be null.
2929 * @return true if the input string is matched, false otherwise.
3030 */
31 public boolean matches(/* @NotNull */String input);
31 boolean matches(/* @NotNull */String input);
3232
3333 /**
3434 * Return if the matcher will match *only* if the expression equals the input. <i> WARN: This is
3535 * used only as a performance trick, to avoid scanning for things when you already know exactly
3636 * what you want. In the install task where it used it avoid scanning the repository to list all
3737 * modules to find that only one matches, and that it has the name requested. </i>
38 *
38 *
3939 * @return true if the matcher only matches when the expression is equals to the input, false
4040 * otherwise.
4141 */
42 public boolean isExact();
42 boolean isExact();
4343 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 /**
2020 * Interface for a pattern matcher.
21 * <p/>
21 * <p>
2222 * The pattern matcher is the main abstraction regarding the matching of an expression.
2323 * Implementation may vary depending on the expression syntax handling that is desired.
24 * </p>
2425 */
2526 public interface PatternMatcher {
2627
2728 /**
2829 * 'exact' pattern matcher name
2930 */
30 public static final String EXACT = "exact";
31 String EXACT = "exact";
3132
3233 /**
3334 * pattern matcher name 'regexp'
3435 */
35 public static final String REGEXP = "regexp";
36 String REGEXP = "regexp";
3637
3738 /**
3839 * pattern matcher 'glob'
3940 */
40 public static final String GLOB = "glob";
41 String GLOB = "glob";
4142
4243 /**
4344 * pattern matcher name 'exactOrRegexp'
4445 */
45 public static final String EXACT_OR_REGEXP = "exactOrRegexp";
46 String EXACT_OR_REGEXP = "exactOrRegexp";
4647
4748 /**
4849 * Any expression string: '*'
4950 */
50 public static final String ANY_EXPRESSION = "*";
51 String ANY_EXPRESSION = "*";
5152
5253 /**
5354 * Return the matcher for the given expression.
54 *
55 *
5556 * @param expression
5657 * the expression to be matched. Cannot be null ?
5758 * @return the matcher instance for the given expression. Never null.
5859 */
59 public/* @NotNull */Matcher getMatcher(/* @NotNull */String expression);
60 /* @NotNull */Matcher getMatcher(/* @NotNull */String expression);
6061
6162 /**
6263 * return the name of this pattern matcher
63 *
64 *
6465 * @return the name of this pattern matcher. Never null.
6566 * @see #EXACT
6667 * @see #REGEXP
6768 * @see #GLOB
6869 * @see #EXACT_OR_REGEXP
6970 */
70 public/* @NotNull */String getName();
71 /* @NotNull */String getName();
7172 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 /**
2323 * A pattern matcher matching input using regular expressions.
24 *
24 *
2525 * @see Pattern
2626 */
2727 public final/* @Immutable */class RegexpPatternMatcher extends AbstractPatternMatcher {
3737 super(REGEXP);
3838 }
3939
40 @Override
4041 protected Matcher newMatcher(String expression) {
4142 return new RegexpMatcher(expression);
4243 }
6768 if (exact == null) {
6869 exact = calculateExact();
6970 }
70 return exact.booleanValue();
71 return exact;
7172 }
7273
7374 private Boolean calculateExact() {
7475 Boolean result = Boolean.TRUE;
7576
76 char[] expressionChars = expression.toCharArray();
77 for (int i = 0; i < expressionChars.length; i++) {
78 char ch = expressionChars[i];
77 for (char ch : expression.toCharArray()) {
7978 if (!Character.isLetterOrDigit(ch) && !Character.isWhitespace(ch) && ('-' != ch)
8079 && ('_' != ch)) {
8180 result = Boolean.FALSE;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.plugins.namespace;
1818
1919 import java.util.ArrayList;
20 import java.util.Iterator;
2120 import java.util.List;
2221 import java.util.regex.Matcher;
2322 import java.util.regex.Pattern;
5150 }
5251 }
5352 matchers[3] = Pattern.compile(getPattern(src.getRev())).matcher(mrid.getRevision());
54 if (!matchers[3].matches()) {
55 return false;
56 }
57
58 return true;
53 return matchers[3].matches();
5954 // CheckStyle:MagicNumber| ON
6055 }
6156
8176 return rule;
8277 }
8378 String res = rule == null ? "$" + ruleType + "0" : rule;
84 for (int i = 0; i < TYPES.length; i++) {
85 if (TYPES[i].equals(type)) {
79 for (String tp : TYPES) {
80 if (tp.equals(type)) {
8681 res = res.replaceAll("([^\\\\])\\$" + type, "$1\\$");
8782 res = res.replaceAll("^\\$" + type, "\\$");
8883 } else {
89 res = res.replaceAll("([^\\\\])\\$" + TYPES[i], "$1\\\\\\$" + TYPES[i]);
90 res = res.replaceAll("^\\$" + TYPES[i], "\\\\\\$" + TYPES[i]);
84 res = res.replaceAll("([^\\\\])\\$" + tp, "$1\\\\\\$" + tp);
85 res = res.replaceAll("^\\$" + tp, "\\\\\\$" + tp);
9186 }
9287 }
9388
110105 }
111106 }
112107
113 private List src = new ArrayList();
108 private final List<MRIDRule> src = new ArrayList<>();
114109
115110 private MRIDRule dest;
116111
127122
128123 public ModuleRevisionId transform(ModuleRevisionId mrid) {
129124 MridRuleMatcher matcher = new MridRuleMatcher();
130 for (Iterator iter = src.iterator(); iter.hasNext();) {
131 MRIDRule rule = (MRIDRule) iter.next();
125 for (MRIDRule rule : src) {
132126 if (matcher.match(rule, mrid)) {
133127 ModuleRevisionId destMrid = matcher.apply(dest, mrid);
134128 Message.debug("found matching namespace rule: " + rule + ". Applied " + dest
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.plugins.namespace;
1818
1919 import java.util.ArrayList;
20 import java.util.Iterator;
2120 import java.util.List;
2221
2322 import org.apache.ivy.core.module.id.ModuleRevisionId;
2827 SYSTEM_NAMESPACE = new Namespace();
2928 }
3029
31 private List/* <NamespaceRule> */rules = new ArrayList();
30 private final List<NamespaceRule> rules = new ArrayList<>();
3231
3332 private String name;
3433
3938 if (mrid == null) {
4039 return null;
4140 }
42 for (Iterator iter = rules.iterator(); iter.hasNext();) {
43 NamespaceRule rule = (NamespaceRule) iter.next();
41 for (NamespaceRule rule : rules) {
4442 ModuleRevisionId nmrid = rule.getFromSystem().transform(mrid);
4543 if (chainRules) {
4644 mrid = nmrid;
6159 if (mrid == null) {
6260 return null;
6361 }
64 for (Iterator iter = rules.iterator(); iter.hasNext();) {
65 NamespaceRule rule = (NamespaceRule) iter.next();
62 for (NamespaceRule rule : rules) {
6663 ModuleRevisionId nmrid = rule.getToSystem().transform(mrid);
6764 if (chainRules) {
6865 mrid = nmrid;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.ivy.core.module.id.ModuleRevisionId;
2020
2121 public interface NamespaceTransformer {
22 public ModuleRevisionId transform(ModuleRevisionId mrid);
22 ModuleRevisionId transform(ModuleRevisionId mrid);
2323
24 public boolean isIdentity();
24 boolean isIdentity();
2525 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4141 import org.xml.sax.SAXParseException;
4242 import org.xml.sax.helpers.DefaultHandler;
4343
44 import static org.apache.ivy.util.StringUtils.splitToArray;
45
4446 public abstract class AbstractModuleDescriptorParser implements ModuleDescriptorParser {
4547 public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
4648 boolean validate) throws ParseException, IOException {
6062
6163 private String defaultConf; // used only as defaultconf, not used for
6264
63 // guesssing right side part of a mapping
65 // guessing right side part of a mapping
6466 private String defaultConfMapping; // same as default conf but is used
6567
66 // for guesssing right side part of a mapping
68 // for guessing right side part of a mapping
6769 private DefaultDependencyDescriptor defaultConfMappingDescriptor;
6870
6971 private Resource res;
7072
71 private List errors = new ArrayList();
73 private List<String> errors = new ArrayList<>();
7274
7375 private DefaultModuleDescriptor md;
7476
112114 }
113115
114116 protected void parseDepsConfs(String confs, DefaultDependencyDescriptor dd,
115 boolean useDefaultMappingToGuessRightOperande) {
116 parseDepsConfs(confs, dd, useDefaultMappingToGuessRightOperande, true);
117 boolean useDefaultMappingToGuessRightOperand) {
118 parseDepsConfs(confs, dd, useDefaultMappingToGuessRightOperand, true);
117119 }
118120
119121 protected void parseDepsConfs(String confs, DefaultDependencyDescriptor dd,
120 boolean useDefaultMappingToGuessRightOperande, boolean evaluateConditions) {
122 boolean useDefaultMappingToGuessRightOperand, boolean evaluateConditions) {
121123 if (confs == null) {
122124 return;
123125 }
124126
125 String[] conf = confs.split(";");
126 parseDepsConfs(conf, dd, useDefaultMappingToGuessRightOperande, evaluateConditions);
127 String[] conf = confs.trim().split("\\s*;\\s*");
128 parseDepsConfs(conf, dd, useDefaultMappingToGuessRightOperand, evaluateConditions);
127129 }
128130
129131 protected void parseDepsConfs(String[] conf, DefaultDependencyDescriptor dd,
130 boolean useDefaultMappingToGuessRightOperande) {
131 parseDepsConfs(conf, dd, useDefaultMappingToGuessRightOperande, true);
132 }
133
134 protected void parseDepsConfs(String[] conf, DefaultDependencyDescriptor dd,
135 boolean useDefaultMappingToGuessRightOperande, boolean evaluateConditions) {
132 boolean useDefaultMappingToGuessRightOperand) {
133 parseDepsConfs(conf, dd, useDefaultMappingToGuessRightOperand, true);
134 }
135
136 protected void parseDepsConfs(String[] confs, DefaultDependencyDescriptor dd,
137 boolean useDefaultMappingToGuessRightOperand, boolean evaluateConditions) {
136138 replaceConfigurationWildcards(md);
137 for (int i = 0; i < conf.length; i++) {
138 String[] ops = conf[i].split("->");
139 if (ops.length == 1) {
140 String[] modConfs = ops[0].split(",");
141 if (!useDefaultMappingToGuessRightOperande) {
142 for (int j = 0; j < modConfs.length; j++) {
143 dd.addDependencyConfiguration(modConfs[j].trim(), modConfs[j].trim());
144 }
145 } else {
146 for (int j = 0; j < modConfs.length; j++) {
147 String[] depConfs = getDefaultConfMappingDescriptor()
148 .getDependencyConfigurations(modConfs[j]);
149 if (depConfs.length > 0) {
150 for (int k = 0; k < depConfs.length; k++) {
151 String mappedDependency = evaluateConditions ? evaluateCondition(
152 depConfs[k].trim(), dd) : depConfs[k].trim();
153 if (mappedDependency != null) {
154 dd.addDependencyConfiguration(modConfs[j].trim(),
155 mappedDependency);
139 for (String conf : confs) {
140 String[] ops = conf.split("->");
141 switch (ops.length) {
142 case 1:
143 for (String modConf : splitToArray(ops[0])) {
144 if (useDefaultMappingToGuessRightOperand) {
145 String[] depConfs = getDefaultConfMappingDescriptor()
146 .getDependencyConfigurations(modConf);
147 if (depConfs.length > 0) {
148 for (String depConf : depConfs) {
149 String mappedDependency = evaluateConditions ? evaluateCondition(
150 depConf.trim(), dd) : depConf.trim();
151 if (mappedDependency != null) {
152 dd.addDependencyConfiguration(modConf,
153 mappedDependency);
154 }
156155 }
156 } else {
157 // no default mapping found for this configuration, map
158 // configuration to itself
159 dd.addDependencyConfiguration(modConf, modConf);
157160 }
158161 } else {
159 // no default mapping found for this configuration, map
160 // configuration to itself
161 dd.addDependencyConfiguration(modConfs[j].trim(),
162 modConfs[j].trim());
162 dd.addDependencyConfiguration(modConf, modConf);
163163 }
164164 }
165 }
166 } else if (ops.length == 2) {
167 String[] modConfs = ops[0].split(",");
168 String[] depConfs = ops[1].split(",");
169 for (int j = 0; j < modConfs.length; j++) {
170 for (int k = 0; k < depConfs.length; k++) {
171 String mappedDependency = evaluateConditions ? evaluateCondition(
172 depConfs[k].trim(), dd) : depConfs[k].trim();
173 if (mappedDependency != null) {
174 dd.addDependencyConfiguration(modConfs[j].trim(), mappedDependency);
165 break;
166 case 2:
167 for (String modConf : splitToArray(ops[0])) {
168 for (String depConf : splitToArray(ops[1])) {
169 String mappedDependency = evaluateConditions ? evaluateCondition(
170 depConf, dd) : depConf;
171 if (mappedDependency != null) {
172 dd.addDependencyConfiguration(modConf, mappedDependency);
173 }
175174 }
176175 }
177 }
178 } else {
179 addError("invalid conf " + conf[i] + " for " + dd);
176 break;
177 default:
178 addError("invalid conf " + conf + " for " + dd);
179 break;
180180 }
181181 }
182182
183183 if (md.isMappingOverride()) {
184 addExtendingConfigurations(conf, dd, useDefaultMappingToGuessRightOperande);
184 addExtendingConfigurations(confs, dd, useDefaultMappingToGuessRightOperand);
185185 }
186186 }
187187
188188 /**
189189 * Evaluate the optional condition in the given configuration, like "[org=MYORG]confX". If
190190 * the condition evaluates to true, the configuration is returned, if the condition
191 * evaluatate to false, null is returned. If there are no conditions, the configuration
191 * evaluates to false, null is returned. If there are no conditions, the configuration
192192 * itself is returned.
193 *
193 *
194194 * @param conf
195195 * the configuration to evaluate
196196 * @param dd
197 * the dependencydescriptor to which the configuration will be added
197 * the dependency descriptor to which the configuration will be added
198198 * @return the evaluated condition
199199 */
200200 private String evaluateCondition(String conf, DefaultDependencyDescriptor dd) {
249249 }
250250
251251 private void addExtendingConfigurations(String[] confs, DefaultDependencyDescriptor dd,
252 boolean useDefaultMappingToGuessRightOperande) {
253 for (int i = 0; i < confs.length; i++) {
254 addExtendingConfigurations(confs[i], dd, useDefaultMappingToGuessRightOperande);
252 boolean useDefaultMappingToGuessRightOperand) {
253 for (String conf : confs) {
254 addExtendingConfigurations(conf, dd, useDefaultMappingToGuessRightOperand);
255255 }
256256 }
257257
258258 private void addExtendingConfigurations(String conf, DefaultDependencyDescriptor dd,
259 boolean useDefaultMappingToGuessRightOperande) {
260 Set configsToAdd = new HashSet();
261 Configuration[] configs = md.getConfigurations();
262 for (int i = 0; i < configs.length; i++) {
263 String[] ext = configs[i].getExtends();
264 for (int j = 0; j < ext.length; j++) {
265 if (conf.equals(ext[j])) {
266 String configName = configs[i].getName();
259 boolean useDefaultMappingToGuessRightOperand) {
260 Set<String> configsToAdd = new HashSet<>();
261 for (Configuration config : md.getConfigurations()) {
262 for (String ext : config.getExtends()) {
263 if (conf.equals(ext)) {
264 String configName = config.getName();
267265 configsToAdd.add(configName);
268266 addExtendingConfigurations(configName, dd,
269 useDefaultMappingToGuessRightOperande);
267 useDefaultMappingToGuessRightOperand);
270268 }
271269 }
272270 }
273271
274 String[] confs = (String[]) configsToAdd.toArray(new String[configsToAdd.size()]);
275 parseDepsConfs(confs, dd, useDefaultMappingToGuessRightOperande);
272 parseDepsConfs(configsToAdd.toArray(new String[configsToAdd.size()]),
273 dd, useDefaultMappingToGuessRightOperand);
276274 }
277275
278276 protected DependencyDescriptor getDefaultConfMappingDescriptor() {
292290 }
293291 }
294292
293 @Override
295294 public void warning(SAXParseException ex) {
296295 Message.warn("xml parsing: " + getLocationString(ex) + ": " + ex.getMessage());
297296 }
298297
298 @Override
299299 public void error(SAXParseException ex) {
300300 addError("xml parsing: " + getLocationString(ex) + ": " + ex.getMessage());
301301 }
302302
303 @Override
303304 public void fatalError(SAXParseException ex) throws SAXException {
304305 addError("[Fatal Error] " + getLocationString(ex) + ": " + ex.getMessage());
305306 }
306307
307308 /** Returns a string of the location. */
308309 private String getLocationString(SAXParseException ex) {
309 StringBuffer str = new StringBuffer();
310 StringBuilder str = new StringBuilder();
310311
311312 String systemId = ex.getSystemId();
312313 if (systemId != null) {
328329 } // getLocationString(SAXParseException):String
329330
330331 protected String getDefaultConf() {
331 return defaultConf != null ? defaultConf
332 : (defaultConfMapping != null ? defaultConfMapping : DEFAULT_CONF_MAPPING);
332 return (defaultConf != null) ? defaultConf
333 : (defaultConfMapping != null) ? defaultConfMapping : DEFAULT_CONF_MAPPING;
333334 }
334335
335336 protected void setDefaultConf(String defaultConf) {
347348 }
348349
349350 private void replaceConfigurationWildcards(ModuleDescriptor md) {
350 Configuration[] configs = md.getConfigurations();
351 for (int i = 0; i < configs.length; i++) {
352 configs[i].replaceWildcards(md);
351 for (Configuration config : md.getConfigurations()) {
352 config.replaceWildcards(md);
353353 }
354354 }
355355
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 import org.apache.ivy.plugins.repository.Resource;
2929
3030 public interface ModuleDescriptorParser {
31 public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
31 ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
3232 boolean validate) throws ParseException, IOException;
3333
34 public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
34 ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL descriptorURL,
3535 Resource res, boolean validate) throws ParseException, IOException;
3636
3737 /**
3838 * Convert a module descriptor to an ivy file. This method MUST close the given input stream
3939 * when job is finished
40 *
41 * @param is
42 * input stream with opened on original module descriptor resource
40 *
41 * @param is input stream with opened on original module descriptor resource
42 * @param res Resource
43 * @param destFile File
44 * @param md ModuleDescriptor
45 * @throws ParseException if something goes wrong
46 * @throws IOException if something goes wrong
4347 */
44 public void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md)
48 void toIvyFile(InputStream is, Resource res, File destFile, ModuleDescriptor md)
4549 throws ParseException, IOException;
4650
47 public boolean accept(Resource res);
51 boolean accept(Resource res);
4852
4953 /**
5054 * Return the 'type' of module artifacts this parser is parsing
51 *
55 *
5256 * @return the 'type' of module artifacts this parser is parsing
5357 */
54 public String getType();
58 String getType();
5559
5660 /**
5761 * Returns the module metadata artifact corresponding to the given module revision id that this
5862 * parser parses
59 *
63 *
6064 * @param res
6165 * the resource for which the module artifact should be returned
6266 * @param mrid
6367 * the module revision id for which the module artifact should be returned
6468 * @return the module artifact corresponding to the given mrid and resource
6569 */
66 public Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res);
70 Artifact getMetadataArtifact(ModuleRevisionId mrid, Resource res);
6771 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.InputStream;
2222 import java.net.URL;
2323 import java.text.ParseException;
24 import java.util.Iterator;
2524 import java.util.LinkedList;
2625 import java.util.List;
2726
3938 return INSTANCE;
4039 }
4140
42 private List parsers = new LinkedList();
41 private List<ModuleDescriptorParser> parsers = new LinkedList<>();
4342
4443 private ModuleDescriptorParserRegistry() {
4544 parsers.add(PomModuleDescriptorParser.getInstance());
4948
5049 /**
5150 * Adds a the given parser to this registry.
52 *
51 *
5352 * @param parser
5453 * the parser to add
5554 */
6261 }
6362
6463 public ModuleDescriptorParser[] getParsers() {
65 return (ModuleDescriptorParser[]) parsers
66 .toArray(new ModuleDescriptorParser[parsers.size()]);
64 return parsers.toArray(new ModuleDescriptorParser[parsers.size()]);
6765 }
6866
6967 public ModuleDescriptorParser getParser(Resource res) {
70 for (Iterator iter = parsers.iterator(); iter.hasNext();) {
71 ModuleDescriptorParser parser = (ModuleDescriptorParser) iter.next();
68 for (ModuleDescriptorParser parser : parsers) {
7269 if (parser.accept(res)) {
7370 return parser;
7471 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.plugins.parser;
1818
19 import java.io.File;
20 import java.util.Map;
21
2219 import org.apache.ivy.core.RelativeUrlResolver;
2320 import org.apache.ivy.core.cache.ResolutionCacheManager;
2421 import org.apache.ivy.core.module.id.ModuleId;
2522 import org.apache.ivy.core.module.id.ModuleRevisionId;
2623 import org.apache.ivy.core.module.status.StatusManager;
24 import org.apache.ivy.core.settings.TimeoutConstraint;
2725 import org.apache.ivy.plugins.conflict.ConflictManager;
2826 import org.apache.ivy.plugins.matcher.PatternMatcher;
2927 import org.apache.ivy.plugins.namespace.Namespace;
3028 import org.apache.ivy.plugins.resolver.DependencyResolver;
3129
30 import java.io.File;
31 import java.util.Map;
32
3233 public interface ParserSettings {
3334
3435 String substitute(String value);
3536
36 Map/* <String, String> */substitute(Map/* <String, String> */strings);
37 Map<String, String> substitute(Map<String, String> strings);
3738
3839 ResolutionCacheManager getResolutionCacheManager();
3940
5455 String getDefaultBranch(ModuleId moduleId);
5556
5657 /**
57 * Returns the namespace context in which the current descriptor is parsed.
58 * @return the namespace context in which the current descriptor is parsed.
5859 */
5960 Namespace getContextNamespace();
6061
62 String getVariable(String string);
63
64 /**
65 * @param name The name of the {@link TimeoutConstraint}
66 * @return Returns a {@link TimeoutConstraint} which is identified by the passed <code>name</code>. Returns null
67 * if no such {@link TimeoutConstraint} exists
68 */
69 TimeoutConstraint getTimeoutConstraint(String name);
6170 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1515 *
1616 */
1717 package org.apache.ivy.plugins.parser.m2;
18
19 import org.apache.ivy.core.module.id.ModuleId;
1820
1921 import java.util.List;
2022
2729
2830 private String scope;
2931
30 private List /* <ModuleId> */excludedModules;
32 private List<ModuleId> excludedModules;
3133
3234 public DefaultPomDependencyMgt(String groupId, String artifactId, String version, String scope,
33 List /* <ModuleId> */excludedModules) {
35 List<ModuleId> excludedModules) {
3436 this.groupId = groupId;
3537 this.artifactId = artifactId;
3638 this.version = version;
5456 return version;
5557 }
5658
57 public List /* <ModuleId> */getExcludedModules() {
59 public List<ModuleId> getExcludedModules() {
5860 return excludedModules;
5961 }
6062 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 package org.apache.ivy.plugins.parser.m2;
19
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.StringTokenizer;
24
25 /**
26 * Parser that understands Maven version ranges of the form {@code (,1.0]} and such.
27 * More details about such ranges in Maven, can be found
28 * {@link https://cwiki.apache.org/confluence/display/MAVENOLD/Dependency+Mediation+and+Conflict+Resolution#DependencyMediationandConflictResolution-DependencyVersionRanges here}
29 */
30 class MavenVersionRangeParser {
31
32 private static final DeweyDecimal javaVersion;
33
34 static {
35 DeweyDecimal v = null;
36 try {
37 v = new DeweyDecimal(System.getProperty("java.specification.version"));
38 } catch (Exception e) {
39 v = null;
40 }
41 javaVersion = v;
42 }
43
44 /**
45 * @param range The range to compare against
46 * @return Returns true if the current Java version, in which the instance of this class is running,
47 * is within the specified {@code range}. Else returns false.
48 */
49 static boolean currentJavaVersionInRange(final String range) {
50 if (range == null) {
51 return false;
52 }
53 if (javaVersion == null) {
54 // this will almost never be the case, but if we couldn't
55 // determine the version of Java this system is running on,
56 // then there's nothing we can do
57 return false;
58 }
59 final Range parsedRange = parse(range);
60 return parsedRange != null && parsedRange.accepts(javaVersion);
61 }
62
63 /**
64 * @param range The range to compare against
65 * @param value The value being compared
66 * @return Compares the {@code value} against the {@code range} and returns true if the {@code value}
67 * lies within the {@code range}. Else returns false.
68 */
69 static boolean rangeAccepts(final String range, final String value) {
70 if (value == null) {
71 return false;
72 }
73 final DeweyDecimal valToCompare;
74 try {
75 valToCompare = new DeweyDecimal(value);
76 } catch (NumberFormatException nfe) {
77 return false;
78 }
79 final Range parsedRange = parse(range);
80 return parsedRange != null && parsedRange.accepts(valToCompare);
81 }
82
83 private static Range parse(final String rangeValue) {
84 if (rangeValue == null || rangeValue.trim().isEmpty()) {
85 return null;
86 }
87 try {
88 // split the version by ","
89 final String[] versionParts = rangeValue.split(",");
90 if (versionParts.length == 1) {
91 final String boundVal = versionParts[0].trim();
92 final String stripped = stripBoundChars(boundVal);
93 if (stripped.isEmpty()) {
94 return null;
95 }
96 final DeweyDecimal bound = new DeweyDecimal(stripped);
97 return new BasicRange(bound, !boundVal.startsWith("("), bound, !boundVal.endsWith(")"));
98 }
99 if (versionParts.length == 2) {
100 final String lowerBoundVal = versionParts[0].trim();
101 final String strippedLowerBound = stripBoundChars(lowerBoundVal);
102 final DeweyDecimal lowerBound;
103 if (strippedLowerBound.isEmpty()) {
104 lowerBound = null;
105 } else {
106 lowerBound = new DeweyDecimal(strippedLowerBound);
107 }
108 final String upperBoundVal = versionParts[1].trim();
109 final String strippedUpperBound = stripBoundChars(upperBoundVal);
110 final DeweyDecimal upperBound;
111 if (strippedUpperBound.isEmpty()) {
112 upperBound = null;
113 } else {
114 upperBound = new DeweyDecimal(strippedUpperBound);
115 }
116 return new BasicRange(lowerBound, !lowerBoundVal.startsWith("("), upperBound, !upperBoundVal.endsWith(")"));
117 }
118 if (versionParts.length > 2) {
119 // each range part can itself be a range, which is valid in maven
120 final Collection<Range> ranges = new ArrayList<>();
121 for (int i = 0; i < versionParts.length; i = (i + 2 < versionParts.length) ? i + 2 : i + 1) {
122 final String partOne = versionParts[i];
123 final String partTwo;
124 if (i + 1 < versionParts.length) {
125 partTwo = versionParts[i + 1];
126 } else {
127 partTwo = "";
128 }
129 final Range rangePart = parse(partOne + "," + partTwo);
130 if (rangePart == null) {
131 continue;
132 }
133 ranges.add(rangePart);
134
135 }
136 return (ranges == null || ranges.isEmpty()) ? null : new MultiSetRange(ranges);
137 }
138 return null;
139 } catch (NumberFormatException nfe) {
140 return null;
141 }
142 }
143
144 private static String stripBoundChars(final String value) {
145 if (value == null) {
146 return null;
147 }
148 return value.replace("(", "").replace(")", "")
149 .replace("[", "").replace("]", "");
150 }
151
152 private interface Range {
153 boolean accepts(final DeweyDecimal value);
154 }
155
156 private static final class BasicRange implements Range {
157 private final DeweyDecimal lowerBound;
158
159 private final DeweyDecimal upperBound;
160
161 private final boolean lowerInclusive;
162
163 private final boolean upperInclusive;
164
165 private BasicRange(final DeweyDecimal lowerBound, final boolean lowerInclusive,
166 final DeweyDecimal upperBound, final boolean upperInclusive) {
167 this.lowerBound = lowerBound;
168 this.lowerInclusive = lowerInclusive;
169 this.upperBound = upperBound;
170 this.upperInclusive = upperInclusive;
171 }
172
173 @Override
174 public boolean accepts(final DeweyDecimal value) {
175 return value != null
176 && (this.lowerBound == null || (this.lowerInclusive ? value.isGreaterThanOrEqual(lowerBound) : value.isGreaterThan(lowerBound)))
177 && (this.upperBound == null || (this.upperInclusive ? value.isLessThanOrEqual(upperBound) : value.isLessThan(upperBound)));
178 }
179 }
180
181 private static final class MultiSetRange implements Range {
182
183 private final Collection<Range> ranges;
184
185 private MultiSetRange(final Collection<Range> ranges) {
186 this.ranges = ranges == null ? Collections.<Range>emptySet() : ranges;
187 }
188
189 @Override
190 public boolean accepts(final DeweyDecimal value) {
191 if (this.ranges.isEmpty()) {
192 return false;
193 }
194 for (final Range range : this.ranges) {
195 if (range == null) {
196 continue;
197 }
198 // if any range matches, we consider it a match
199 if (range.accepts(value)) {
200 return true;
201 }
202 }
203 return false;
204 }
205 }
206
207 // This class is a copy of the one in Ant project, but since Ivy *core* module
208 // (intentionally) doesn't rely on Ant, we use a copied version here
209 private static final class DeweyDecimal {
210
211 /**
212 * Array of components that make up DeweyDecimal
213 */
214 private final int[] components;
215
216 /**
217 * Construct a DeweyDecimal from an array of integer components.
218 *
219 * @param components an array of integer components.
220 */
221 @SuppressWarnings("unused")
222 public DeweyDecimal(final int[] components) {
223 this.components = new int[components.length];
224 System.arraycopy(components, 0, this.components, 0, components.length);
225 }
226
227 /**
228 * Construct a DeweyDecimal from string in DeweyDecimal format.
229 *
230 * @param string the string in dewey decimal format
231 * @throws NumberFormatException if string is malformed
232 */
233 public DeweyDecimal(final String string)
234 throws NumberFormatException {
235 final StringTokenizer tokenizer = new StringTokenizer(string, ".", true);
236 final int size = tokenizer.countTokens();
237
238 components = new int[(size + 1) / 2];
239
240 for (int i = 0; i < components.length; i++) {
241 final String component = tokenizer.nextToken();
242 if (component.length() == 0) {
243 throw new NumberFormatException("Empty component in string");
244 }
245
246 components[i] = Integer.parseInt(component);
247
248 // Strip '.' token
249 if (tokenizer.hasMoreTokens()) {
250 tokenizer.nextToken();
251
252 // If it ended in a dot, throw an exception
253 if (!tokenizer.hasMoreTokens()) {
254 throw new NumberFormatException("DeweyDecimal ended in a '.'");
255 }
256 }
257 }
258 }
259
260 /**
261 * Return number of components in <code>DeweyDecimal</code>.
262 *
263 * @return the number of components in dewey decimal
264 */
265 @SuppressWarnings("unused")
266 public int getSize() {
267 return components.length;
268 }
269
270 /**
271 * Return the component at specified index.
272 *
273 * @param index the index of components
274 * @return the value of component at index
275 */
276 @SuppressWarnings("unused")
277 public int get(final int index) {
278 return components[index];
279 }
280
281 /**
282 * Return <code>true</code> if this <code>DeweyDecimal</code> is
283 * equal to the other <code>DeweyDecimal</code>.
284 *
285 * @param other the other DeweyDecimal
286 * @return true if equal to other DeweyDecimal, false otherwise
287 */
288 public boolean isEqual(final DeweyDecimal other) {
289 final int max = Math.max(other.components.length, components.length);
290
291 for (int i = 0; i < max; i++) {
292 final int component1 = (i < components.length) ? components[i] : 0;
293 final int component2 = (i < other.components.length) ? other.components[i] : 0;
294
295 if (component2 != component1) {
296 return false;
297 }
298 }
299
300 return true; // Exact match
301 }
302
303 /**
304 * Return <code>true</code> if this <code>DeweyDecimal</code> is
305 * less than the other <code>DeweyDecimal</code>.
306 *
307 * @param other the other DeweyDecimal
308 * @return true if less than other DeweyDecimal, false otherwise
309 */
310 public boolean isLessThan(final DeweyDecimal other) {
311 return !isGreaterThanOrEqual(other);
312 }
313
314 /**
315 * Return <code>true</code> if this <code>DeweyDecimal</code> is
316 * less than or equal to the other <code>DeweyDecimal</code>.
317 *
318 * @param other the other DeweyDecimal
319 * @return true if less than or equal to other DeweyDecimal, false otherwise
320 */
321 public boolean isLessThanOrEqual(final DeweyDecimal other) {
322 return !isGreaterThan(other);
323 }
324
325 /**
326 * Return <code>true</code> if this <code>DeweyDecimal</code> is
327 * greater than the other <code>DeweyDecimal</code>.
328 *
329 * @param other the other DeweyDecimal
330 * @return true if greater than other DeweyDecimal, false otherwise
331 */
332 public boolean isGreaterThan(final DeweyDecimal other) {
333 final int max = Math.max(other.components.length, components.length);
334
335 for (int i = 0; i < max; i++) {
336 final int component1 = (i < components.length) ? components[i] : 0;
337 final int component2 = (i < other.components.length) ? other.components[i] : 0;
338
339 if (component2 > component1) {
340 return false;
341 }
342 if (component2 < component1) {
343 return true;
344 }
345 }
346
347 return false; // Exact match
348 }
349
350 /**
351 * Return <code>true</code> if this <code>DeweyDecimal</code> is
352 * greater than or equal to the other <code>DeweyDecimal</code>.
353 *
354 * @param other the other DeweyDecimal
355 * @return true if greater than or equal to other DeweyDecimal, false otherwise
356 */
357 public boolean isGreaterThanOrEqual(final DeweyDecimal other) {
358 final int max = Math.max(other.components.length, components.length);
359
360 for (int i = 0; i < max; i++) {
361 final int component1 = (i < components.length) ? components[i] : 0;
362 final int component2 = (i < other.components.length) ? other.components[i] : 0;
363
364 if (component2 > component1) {
365 return false;
366 }
367 if (component2 < component1) {
368 return true;
369 }
370 }
371
372 return true; // Exact match
373 }
374
375 /**
376 * Return string representation of <code>DeweyDecimal</code>.
377 *
378 * @return the string representation of DeweyDecimal.
379 */
380 @Override
381 public String toString() {
382 final StringBuilder sb = new StringBuilder();
383
384 for (int component : components) {
385 if (sb.length() > 0) {
386 sb.append('.');
387 }
388 sb.append(component);
389 }
390
391 return sb.toString();
392 }
393
394 /**
395 * Compares this DeweyDecimal with another one.
396 *
397 * @param other another DeweyDecimal to compare with
398 * @return result
399 * @see java.lang.Comparable#compareTo(Object)
400 */
401 @SuppressWarnings("unused")
402 public int compareTo(DeweyDecimal other) {
403 final int max = Math.max(other.components.length, components.length);
404 for (int i = 0; i < max; i++) {
405 final int component1 = (i < components.length) ? components[i] : 0;
406 final int component2 = (i < other.components.length) ? other.components[i] : 0;
407 if (component1 != component2) {
408 return component1 - component2;
409 }
410 }
411 return 0;
412 }
413
414 @Override
415 public int hashCode() {
416 return toString().hashCode();
417 }
418
419 @Override
420 public boolean equals(Object o) {
421 return o instanceof DeweyDecimal && isEqual((DeweyDecimal) o);
422 }
423 }
424 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.List;
2020
21 import org.apache.ivy.core.module.id.ModuleId;
22
2123 public interface PomDependencyMgt {
2224
23 public abstract String getGroupId();
25 String getGroupId();
2426
25 public abstract String getArtifactId();
27 String getArtifactId();
2628
27 public abstract String getVersion();
29 String getVersion();
2830
29 public abstract String getScope();
31 String getScope();
3032
31 public List /* <ModuleId> */getExcludedModules();
32 }
33 List<ModuleId> getExcludedModules();
34 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.util.Collections;
2323 import java.util.Date;
2424 import java.util.HashMap;
25 import java.util.Iterator;
2625 import java.util.LinkedHashMap;
2726 import java.util.LinkedList;
2827 import java.util.List;
2928 import java.util.Map;
30 import java.util.Map.Entry;
31
32 import org.apache.ivy.Ivy;
29
3330 import org.apache.ivy.core.cache.ArtifactOrigin;
3431 import org.apache.ivy.core.module.descriptor.Artifact;
3532 import org.apache.ivy.core.module.descriptor.Configuration;
36 import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
3733 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
3834 import org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor;
3935 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
5753 import org.apache.ivy.plugins.resolver.DependencyResolver;
5854 import org.apache.ivy.util.Message;
5955
56 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
57 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
58
6059 /**
6160 * Build a module descriptor. This class handle the complexity of the structure of an ivy
6261 * ModuleDescriptor and isolate the PomModuleDescriptorParser from it.
6362 */
6463 public class PomModuleDescriptorBuilder {
6564
65 /**
66 * The namespace URI which is used to refer to Maven (pom) specific elements within a
67 * Ivy module descriptor file (ivy.xml)
68 */
69 private static final String IVY_XML_MAVEN_NAMESPACE_URI = "http://ant.apache.org/ivy/maven";
70
6671 private static final int DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT = 4;
6772
6873 public static final Configuration[] MAVEN2_CONFIGURATIONS = new Configuration[] {
69 new Configuration("default", Visibility.PUBLIC,
74 new Configuration("default", PUBLIC,
7075 "runtime dependencies and master artifact can be used with this conf",
7176 new String[] {"runtime", "master"}, true, null),
72 new Configuration("master", Visibility.PUBLIC,
77 new Configuration("master", PUBLIC,
7378 "contains only the artifact published by this module itself, "
7479 + "with no transitive dependencies", new String[0], true, null),
75 new Configuration("compile", Visibility.PUBLIC,
80 new Configuration("compile", PUBLIC,
7681 "this is the default scope, used if none is specified. "
7782 + "Compile dependencies are available in all classpaths.",
7883 new String[0], true, null),
79 new Configuration(
80 "provided",
81 Visibility.PUBLIC,
84 new Configuration("provided", PUBLIC,
8285 "this is much like compile, but indicates you expect the JDK or a container "
8386 + "to provide it. "
8487 + "It is only available on the compilation classpath, and is not transitive.",
8588 new String[0], true, null),
86 new Configuration("runtime", Visibility.PUBLIC,
89 new Configuration("runtime", PUBLIC,
8790 "this scope indicates that the dependency is not required for compilation, "
8891 + "but is for execution. It is in the runtime and test classpaths, "
8992 + "but not the compile classpath.", new String[] {"compile"}, true,
9093 null),
91 new Configuration(
92 "test",
93 Visibility.PRIVATE,
94 new Configuration("test", PUBLIC,
9495 "this scope indicates that the dependency is not required for normal use of "
9596 + "the application, and is only available for the test compilation and "
9697 + "execution phases.", new String[] {"runtime"}, true, null),
97 new Configuration(
98 "system",
99 Visibility.PUBLIC,
98 new Configuration("system", PUBLIC,
10099 "this scope is similar to provided except that you have to provide the JAR "
101100 + "which contains it explicitly. The artifact is always available and is not "
102101 + "looked up in a repository.", new String[0], true, null),
103 new Configuration("sources", Visibility.PUBLIC,
102 new Configuration("sources", PUBLIC,
104103 "this configuration contains the source artifact of this module, if any.",
105104 new String[0], true, null),
106 new Configuration("javadoc", Visibility.PUBLIC,
105 new Configuration("javadoc", PUBLIC,
107106 "this configuration contains the javadoc artifact of this module, if any.",
108107 new String[0], true, null),
109 new Configuration("optional", Visibility.PUBLIC, "contains all optional dependencies",
108 new Configuration("optional", PUBLIC, "contains all optional dependencies",
110109 new String[0], true, null)};
111110
112 static final Map MAVEN2_CONF_MAPPING = new HashMap();
111 static final Map<String, ConfMapper> MAVEN2_CONF_MAPPING = new HashMap<>();
113112
114113 private static final String DEPENDENCY_MANAGEMENT = "m:dependency.management";
115114
117116
118117 private static final String EXTRA_INFO_DELIMITER = "__";
119118
120 private static final Collection/* <String> */JAR_PACKAGINGS = Arrays.asList(new String[] {
121 "ejb", "bundle", "maven-plugin", "eclipse-plugin", "jbi-component",
122 "jbi-shared-library", "orbit", "hk2-jar"});
123
124 static interface ConfMapper {
125 public void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional);
119 private static final Collection<String> JAR_PACKAGINGS = Arrays.asList("ejb",
120 "bundle", "maven-plugin", "eclipse-plugin", "jbi-component", "jbi-shared-library",
121 "orbit", "hk2-jar");
122
123 interface ConfMapper {
124 void addMappingConfs(DefaultDependencyDescriptor dd, boolean isOptional);
126125 }
127126
128127 static {
200199 ParserSettings ivySettings) {
201200 ivyModuleDescriptor = new PomModuleDescriptor(parser, res);
202201 ivyModuleDescriptor.setResolvedPublicationDate(new Date(res.getLastModified()));
203 for (int i = 0; i < MAVEN2_CONFIGURATIONS.length; i++) {
204 ivyModuleDescriptor.addConfiguration(MAVEN2_CONFIGURATIONS[i]);
202 for (Configuration m2conf : MAVEN2_CONFIGURATIONS) {
203 ivyModuleDescriptor.addConfiguration(m2conf);
205204 }
206205 ivyModuleDescriptor.setMappingOverride(true);
207 ivyModuleDescriptor.addExtraAttributeNamespace("m", Ivy.getIvyHomeURL() + "maven");
206 ivyModuleDescriptor.addExtraAttributeNamespace("m", IVY_XML_MAVEN_NAMESPACE_URI);
208207 parserSettings = ivySettings;
209208 }
210209
216215 mrid = ModuleRevisionId.newInstance(groupId, artifactId, version);
217216 ivyModuleDescriptor.setModuleRevisionId(mrid);
218217
219 if ((version == null) || version.endsWith("SNAPSHOT")) {
218 if (version == null || version.endsWith("SNAPSHOT")) {
220219 ivyModuleDescriptor.setStatus("integration");
221220 } else {
222221 ivyModuleDescriptor.setStatus("release");
232231 }
233232
234233 public void setLicenses(License[] licenses) {
235 for (int i = 0; i < licenses.length; i++) {
236 ivyModuleDescriptor.addLicense(licenses[i]);
234 for (License license : licenses) {
235 ivyModuleDescriptor.addLicense(license);
237236 }
238237 }
239238
274273
275274 public void addDependency(Resource res, PomDependencyData dep) {
276275 String scope = dep.getScope();
277 if ((scope != null) && (scope.length() > 0) && !MAVEN2_CONF_MAPPING.containsKey(scope)) {
276 if (!isNullOrEmpty(scope) && !MAVEN2_CONF_MAPPING.containsKey(scope)) {
278277 // unknown scope, defaulting to 'compile'
279278 scope = "compile";
280279 }
281280
282281 String version = dep.getVersion();
283 version = (version == null || version.length() == 0) ? getDefaultVersion(dep) : version;
282 if (isNullOrEmpty(version)) {
283 version = getDefaultVersion(dep);
284 }
284285 ModuleRevisionId moduleRevId = ModuleRevisionId.newInstance(dep.getGroupId(),
285286 dep.getArtifactId(), version);
286287
287 // Some POMs depend on theirselfves, don't add this dependency: Ivy doesn't allow this!
288 // Some POMs depend on themselves; Ivy doesn't allow this. Don't add this dependency!
288289 // Example: https://repo1.maven.org/maven2/net/jini/jsk-platform/2.1/jsk-platform-2.1.pom
289290 ModuleRevisionId mRevId = ivyModuleDescriptor.getModuleRevisionId();
290 if ((mRevId != null) && mRevId.getModuleId().equals(moduleRevId.getModuleId())) {
291 if (mRevId != null && mRevId.getModuleId().equals(moduleRevId.getModuleId())) {
291292 return;
292293 }
293
294 DefaultDependencyDescriptor dd = new PomDependencyDescriptor(dep, ivyModuleDescriptor,
295 moduleRevId);
296 scope = (scope == null || scope.length() == 0) ? getDefaultScope(dep) : scope;
297 ConfMapper mapping = (ConfMapper) MAVEN2_CONF_MAPPING.get(scope);
294 // experimentation shows the following, excluded modules are
295 // inherited from parent POMs if either of the following is true:
296 // the <exclusions> element is missing or the <exclusions> element
297 // is present, but empty.
298 List<ModuleId> excluded = dep.getExcludedModules();
299 if (excluded.isEmpty()) {
300 excluded = getDependencyMgtExclusions(ivyModuleDescriptor, dep.getGroupId(),
301 dep.getArtifactId());
302 }
303 final boolean excludeAllTransitiveDeps = shouldExcludeAllTransitiveDeps(excluded);
304 // the same dependency mrid could appear twice in the module descriptor,
305 // so we check if we already have created a dependency descriptor for the dependency mrid
306 final DependencyDescriptor existing = this.ivyModuleDescriptor.depDescriptors.get(moduleRevId);
307 final DefaultDependencyDescriptor dd = (existing != null && existing instanceof DefaultDependencyDescriptor)
308 ? (DefaultDependencyDescriptor) existing
309 : new PomDependencyDescriptor(dep, ivyModuleDescriptor, moduleRevId, !excludeAllTransitiveDeps);
310 if (isNullOrEmpty(scope)) {
311 scope = getDefaultScope(dep);
312 }
313 ConfMapper mapping = MAVEN2_CONF_MAPPING.get(scope);
298314 mapping.addMappingConfs(dd, dep.isOptional());
299 Map extraAtt = new HashMap();
300 if ((dep.getClassifier() != null)
301 || ((dep.getType() != null) && !"jar".equals(dep.getType()))) {
315 Map<String, String> extraAtt = new HashMap<>();
316 if (dep.getClassifier() != null || dep.getType() != null && !"jar".equals(dep.getType())) {
302317 String type = "jar";
303318 if (dep.getType() != null) {
304319 type = dep.getType();
319334 if (dep.getClassifier() != null) {
320335 extraAtt.put("m:classifier", dep.getClassifier());
321336 }
322 DefaultDependencyArtifactDescriptor depArtifact = new DefaultDependencyArtifactDescriptor(
337 final DefaultDependencyArtifactDescriptor depArtifact = new DefaultDependencyArtifactDescriptor(
323338 dd, dd.getDependencyId().getName(), type, ext, null, extraAtt);
324339 // here we have to assume a type and ext for the artifact, so this is a limitation
325340 // compared to how m2 behave with classifiers
326 String optionalizedScope = dep.isOptional() ? "optional" : scope;
341 final String optionalizedScope = dep.isOptional() ? "optional" : scope;
342 depArtifact.addConfiguration(optionalizedScope);
327343 dd.addDependencyArtifact(optionalizedScope, depArtifact);
328344 }
329345
330 // experimentation shows the following, excluded modules are
331 // inherited from parent POMs if either of the following is true:
332 // the <exclusions> element is missing or the <exclusions> element
333 // is present, but empty.
334 List /* <ModuleId> */excluded = dep.getExcludedModules();
335 if (excluded.isEmpty()) {
336 excluded = getDependencyMgtExclusions(ivyModuleDescriptor, dep.getGroupId(),
337 dep.getArtifactId());
338 }
339 for (Iterator itExcl = excluded.iterator(); itExcl.hasNext();) {
340 ModuleId excludedModule = (ModuleId) itExcl.next();
341 String[] confs = dd.getModuleConfigurations();
342 for (int k = 0; k < confs.length; k++) {
343 dd.addExcludeRule(confs[k], new DefaultExcludeRule(new ArtifactId(excludedModule,
346 for (ModuleId excludedModule : excluded) {
347 // This represents exclude all transitive dependencies, which we have already taken
348 // in account while defining the DefaultDependencyDescriptor itself
349 if ("*".equals(excludedModule.getOrganisation()) && "*".equals(excludedModule.getName())) {
350 continue;
351 }
352 for (String conf : dd.getModuleConfigurations()) {
353 dd.addExcludeRule(conf, new DefaultExcludeRule(new ArtifactId(excludedModule,
344354 PatternMatcher.ANY_EXPRESSION, PatternMatcher.ANY_EXPRESSION,
345355 PatternMatcher.ANY_EXPRESSION), ExactPatternMatcher.INSTANCE, null));
346356 }
347357 }
348
349 ivyModuleDescriptor.addDependency(dd);
358 // intentional identity check to make sure we don't re-add the same dependency
359 if (existing != dd) {
360 ivyModuleDescriptor.addDependency(dd);
361 }
362 }
363
364 private static boolean shouldExcludeAllTransitiveDeps(final List<ModuleId> exclusions) {
365 if (exclusions == null || exclusions.isEmpty()) {
366 return false;
367 }
368 for (final ModuleId exclusion : exclusions) {
369 if (exclusion == null) {
370 continue;
371 }
372 if ("*".equals(exclusion.getOrganisation()) && "*".equals(exclusion.getName())) {
373 return true;
374 }
375 }
376 return false;
350377 }
351378
352379 public void addDependency(DependencyDescriptor descriptor) {
356383 // https://repo1.maven.org/maven2/com/atomikos/atomikos-util/3.6.4/atomikos-util-3.6.4.pom
357384 ModuleId dependencyId = descriptor.getDependencyId();
358385 ModuleRevisionId mRevId = ivyModuleDescriptor.getModuleRevisionId();
359 if ((mRevId != null) && mRevId.getModuleId().equals(dependencyId)) {
386 if (mRevId != null && mRevId.getModuleId().equals(dependencyId)) {
360387 return;
361388 }
362389
374401 overwriteExtraInfoIfExists(scopeKey, dep.getScope());
375402 }
376403 if (!dep.getExcludedModules().isEmpty()) {
377 final String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(
378 dep.getGroupId(), dep.getArtifactId());
404 String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(dep.getGroupId(),
405 dep.getArtifactId());
379406 int index = 0;
380 for (final Iterator iter = dep.getExcludedModules().iterator(); iter.hasNext();) {
381 final ModuleId excludedModule = (ModuleId) iter.next();
407 for (ModuleId excludedModule : dep.getExcludedModules()) {
382408 overwriteExtraInfoIfExists(
383409 exclusionPrefix + index,
384410 excludedModule.getOrganisation() + EXTRA_INFO_DELIMITER
385411 + excludedModule.getName());
386 index += 1;
412 index++;
387413 }
388414 }
389415 // dependency management info is also used for version mediation of transitive dependencies
407433 if (pluginExtraInfo == null) {
408434 pluginExtraInfo = pluginValue;
409435 } else {
410 pluginExtraInfo = pluginExtraInfo + "|" + pluginValue;
436 pluginExtraInfo += "|" + pluginValue;
411437 }
412438 extraInfoByTagName.setContent(pluginExtraInfo);
413439 }
414440
415 public static List /* <PomDependencyMgt> */getPlugins(ModuleDescriptor md) {
416 List result = new ArrayList();
441 public static List<PomDependencyMgt> getPlugins(ModuleDescriptor md) {
442 List<PomDependencyMgt> result = new ArrayList<>();
417443 String plugins = md.getExtraInfoContentByTagName("m:maven.plugins");
418444 if (plugins == null) {
419 return new ArrayList();
420 }
421 String[] pluginsArray = plugins.split("\\|");
422 for (int i = 0; i < pluginsArray.length; i++) {
423 String[] parts = pluginsArray[i].split(EXTRA_INFO_DELIMITER);
445 return new ArrayList<>();
446 }
447 for (String plugin : plugins.split("\\|")) {
448 String[] parts = plugin.split(EXTRA_INFO_DELIMITER);
424449 result.add(new PomPluginElement(parts[0], parts[1], parts[2]));
425450 }
426451
456481 return null;
457482 }
458483
459 public List /* <ModuleId> */getExcludedModules() {
460 return Collections.EMPTY_LIST; // probably not used?
484 public List<ModuleId> getExcludedModules() {
485 return Collections.emptyList(); // probably not used?
461486 }
462487 }
463488
464489 private String getDefaultVersion(PomDependencyData dep) {
465490 ModuleId moduleId = ModuleId.newInstance(dep.getGroupId(), dep.getArtifactId());
466491 if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(moduleId)) {
467 return ((PomDependencyMgt) ivyModuleDescriptor.getDependencyManagementMap().get(
468 moduleId)).getVersion();
492 return ivyModuleDescriptor.getDependencyManagementMap().get(moduleId).getVersion();
469493 }
470494 String key = getDependencyMgtExtraInfoKeyForVersion(dep.getGroupId(), dep.getArtifactId());
471495 return ivyModuleDescriptor.getExtraInfoContentByTagName(key);
475499 String result;
476500 ModuleId moduleId = ModuleId.newInstance(dep.getGroupId(), dep.getArtifactId());
477501 if (ivyModuleDescriptor.getDependencyManagementMap().containsKey(moduleId)) {
478 result = ((PomDependencyMgt) ivyModuleDescriptor.getDependencyManagementMap().get(
479 moduleId)).getScope();
502 result = ivyModuleDescriptor.getDependencyManagementMap().get(moduleId).getScope();
480503 } else {
481504 String key = getDependencyMgtExtraInfoKeyForScope(dep.getGroupId(), dep.getArtifactId());
482505 result = ivyModuleDescriptor.getExtraInfoContentByTagName(key);
483506 }
484 if ((result == null) || !MAVEN2_CONF_MAPPING.containsKey(result)) {
507 if (result == null || !MAVEN2_CONF_MAPPING.containsKey(result)) {
485508 result = "compile";
486509 }
487510 return result;
488511 }
489512
490 private static String getDependencyMgtExtraInfoKeyForVersion(String groupId, String artifaceId) {
513 private static String getDependencyMgtExtraInfoKeyForVersion(String groupId, String artifactId) {
491514 return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER
492 + artifaceId + EXTRA_INFO_DELIMITER + "version";
493 }
494
495 private static String getDependencyMgtExtraInfoKeyForScope(String groupId, String artifaceId) {
515 + artifactId + EXTRA_INFO_DELIMITER + "version";
516 }
517
518 private static String getDependencyMgtExtraInfoKeyForScope(String groupId, String artifactId) {
496519 return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER
497 + artifaceId + EXTRA_INFO_DELIMITER + "scope";
520 + artifactId + EXTRA_INFO_DELIMITER + "scope";
498521 }
499522
500523 private static String getPropertyExtraInfoKey(String propertyName) {
502525 }
503526
504527 private static String getDependencyMgtExtraInfoPrefixForExclusion(String groupId,
505 String artifaceId) {
528 String artifactId) {
506529 return DEPENDENCY_MANAGEMENT + EXTRA_INFO_DELIMITER + groupId + EXTRA_INFO_DELIMITER
507 + artifaceId + EXTRA_INFO_DELIMITER + "exclusion_";
508 }
509
510 private static List /* <ModuleId> */getDependencyMgtExclusions(ModuleDescriptor descriptor,
530 + artifactId + EXTRA_INFO_DELIMITER + "exclusion_";
531 }
532
533 private static List<ModuleId> getDependencyMgtExclusions(ModuleDescriptor descriptor,
511534 String groupId, String artifactId) {
512535 if (descriptor instanceof PomModuleDescriptor) {
513 PomDependencyMgt dependencyMgt = (PomDependencyMgt) ((PomModuleDescriptor) descriptor)
536 PomDependencyMgt dependencyMgt = ((PomModuleDescriptor) descriptor)
514537 .getDependencyManagementMap().get(ModuleId.newInstance(groupId, artifactId));
515538 if (dependencyMgt != null) {
516539 return dependencyMgt.getExcludedModules();
517540 }
518541 }
519542 String exclusionPrefix = getDependencyMgtExtraInfoPrefixForExclusion(groupId, artifactId);
520 List /* <ModuleId> */exclusionIds = new LinkedList /* <ModuleId> */();
543 List<ModuleId> exclusionIds = new LinkedList<>();
521544 for (ExtraInfoHolder extraInfoHolder : descriptor.getExtraInfos()) {
522545 String key = extraInfoHolder.getName();
523546 if (key.startsWith(exclusionPrefix)) {
534557 return exclusionIds;
535558 }
536559
537 public static Map/* <ModuleId, String version> */
538 getDependencyManagementMap(ModuleDescriptor md) {
539 Map ret = new LinkedHashMap();
560 public static Map<ModuleId, String> getDependencyManagementMap(ModuleDescriptor md) {
561 Map<ModuleId, String> ret = new LinkedHashMap<>();
540562 if (md instanceof PomModuleDescriptor) {
541 for (final Iterator iterator = ((PomModuleDescriptor) md).getDependencyManagementMap()
542 .entrySet().iterator(); iterator.hasNext();) {
543 Map.Entry e = (Entry) iterator.next();
544 PomDependencyMgt dependencyMgt = (PomDependencyMgt) e.getValue();
563 for (Map.Entry<ModuleId, PomDependencyMgt> e : ((PomModuleDescriptor) md)
564 .getDependencyManagementMap().entrySet()) {
565 PomDependencyMgt dependencyMgt = e.getValue();
545566 ret.put(e.getKey(), dependencyMgt.getVersion());
546567 }
547568 } else {
548569 for (ExtraInfoHolder extraInfoHolder : md.getExtraInfos()) {
549570 String key = extraInfoHolder.getName();
550 if ((key).startsWith(DEPENDENCY_MANAGEMENT)) {
571 if (key.startsWith(DEPENDENCY_MANAGEMENT)) {
551572 String[] parts = key.split(EXTRA_INFO_DELIMITER);
552573 if (parts.length != DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT) {
553574 Message.warn("what seem to be a dependency management extra info "
562583 return ret;
563584 }
564585
565 public static List getDependencyManagements(ModuleDescriptor md) {
566 List result = new ArrayList();
586 public static List<PomDependencyMgt> getDependencyManagements(ModuleDescriptor md) {
587 List<PomDependencyMgt> result = new ArrayList<>();
567588
568589 if (md instanceof PomModuleDescriptor) {
569590 result.addAll(((PomModuleDescriptor) md).getDependencyManagementMap().values());
570591 } else {
571592 for (ExtraInfoHolder extraInfoHolder : md.getExtraInfos()) {
572593 String key = extraInfoHolder.getName();
573 if ((key).startsWith(DEPENDENCY_MANAGEMENT)) {
594 if (key.startsWith(DEPENDENCY_MANAGEMENT)) {
574595 String[] parts = key.split(EXTRA_INFO_DELIMITER);
575596 if (parts.length != DEPENDENCY_MANAGEMENT_KEY_PARTS_COUNT) {
576597 Message.warn("what seem to be a dependency management extra info "
585606 String version = md.getExtraInfoContentByTagName(versionKey);
586607 String scope = md.getExtraInfoContentByTagName(scopeKey);
587608
588 List /* <ModuleId> */exclusions = getDependencyMgtExclusions(md, parts[1],
609 List<ModuleId> exclusions = getDependencyMgtExclusions(md, parts[1],
589610 parts[2]);
590611 result.add(new DefaultPomDependencyMgt(parts[1], parts[2], version, scope,
591612 exclusions));
597618 }
598619
599620 @Deprecated
600 public void addExtraInfos(Map extraAttributes) {
601 for (Iterator it = extraAttributes.entrySet().iterator(); it.hasNext();) {
602 Map.Entry entry = (Entry) it.next();
603 String key = (String) entry.getKey();
604 String value = (String) entry.getValue();
605 addExtraInfo(key, value);
621 public void addExtraInfos(Map<String, String> extraAttributes) {
622 for (Map.Entry<String, String> entry : extraAttributes.entrySet()) {
623 addExtraInfo(entry.getKey(), entry.getValue());
606624 }
607625 }
608626
632650 }
633651
634652 @Deprecated
635 public static Map extractPomProperties(Map extraInfo) {
636 Map r = new HashMap();
637 for (Iterator it = extraInfo.entrySet().iterator(); it.hasNext();) {
638 Map.Entry extraInfoEntry = (Map.Entry) it.next();
639 if (((String) extraInfoEntry.getKey()).startsWith(PROPERTIES)) {
640 String prop = ((String) extraInfoEntry.getKey()).substring(PROPERTIES.length()
653 public static Map<String, String> extractPomProperties(Map<String, String> extraInfo) {
654 Map<String, String> r = new HashMap<>();
655 for (Map.Entry<String, String> extraInfoEntry : extraInfo.entrySet()) {
656 if (extraInfoEntry.getKey().startsWith(PROPERTIES)) {
657 String prop = extraInfoEntry.getKey().substring(PROPERTIES.length()
641658 + EXTRA_INFO_DELIMITER.length());
642659 r.put(prop, extraInfoEntry.getValue());
643660 }
645662 return r;
646663 }
647664
648 public static Map extractPomProperties(List<ExtraInfoHolder> extraInfos) {
649 Map r = new HashMap();
665 public static Map<String, String> extractPomProperties(List<ExtraInfoHolder> extraInfos) {
666 Map<String, String> r = new HashMap<>();
650667 for (ExtraInfoHolder extraInfoHolder : extraInfos) {
651 if ((extraInfoHolder.getName()).startsWith(PROPERTIES)) {
652 String prop = (extraInfoHolder.getName()).substring(PROPERTIES.length()
668 if (extraInfoHolder.getName().startsWith(PROPERTIES)) {
669 String prop = extraInfoHolder.getName().substring(PROPERTIES.length()
653670 + EXTRA_INFO_DELIMITER.length());
654671 r.put(prop, extraInfoHolder.getContent());
655672 }
700717 private final PomDependencyData pomDependencyData;
701718
702719 private PomDependencyDescriptor(PomDependencyData pomDependencyData,
703 ModuleDescriptor moduleDescriptor, ModuleRevisionId revisionId) {
704 super(moduleDescriptor, revisionId, true, false, true);
720 ModuleDescriptor moduleDescriptor, ModuleRevisionId revisionId, final boolean transitive) {
721 super(moduleDescriptor, revisionId, true, false, transitive);
705722 this.pomDependencyData = pomDependencyData;
706723 }
707724
708725 /**
709726 * Get PomDependencyData.
710 *
727 *
711728 * @return PomDependencyData
712729 */
713730 public PomDependencyData getPomDependencyData() {
716733 }
717734
718735 public static class PomModuleDescriptor extends DefaultModuleDescriptor {
719 private final Map/* <ModuleId, PomDependencyMgt> */dependencyManagementMap = new HashMap();
736 private final Map<ModuleId, PomDependencyMgt> dependencyManagementMap = new LinkedHashMap<>();
737 // dependency descriptor keyed by its dependency revision id
738 private final Map<ModuleRevisionId, DependencyDescriptor> depDescriptors = new HashMap<>();
720739
721740 public PomModuleDescriptor(ModuleDescriptorParser parser, Resource res) {
722741 super(parser, res);
728747 dependencyMgt);
729748 }
730749
731 public Map getDependencyManagementMap() {
750 public Map<ModuleId, PomDependencyMgt> getDependencyManagementMap() {
732751 return dependencyManagementMap;
733752 }
753
754 @Override
755 public void addDependency(final DependencyDescriptor dependency) {
756 super.addDependency(dependency);
757 this.depDescriptors.put(dependency.getDependencyRevisionId(), dependency);
758 }
734759 }
735760 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.InputStream;
2222 import java.net.URL;
2323 import java.text.ParseException;
24 import java.util.ArrayList;
2425 import java.util.Date;
25 import java.util.Iterator;
26 import java.util.LinkedHashSet;
2627 import java.util.List;
2728 import java.util.Map;
29 import java.util.Set;
2830
2931 import org.apache.ivy.core.IvyContext;
3032 import org.apache.ivy.core.cache.ArtifactOrigin;
3133 import org.apache.ivy.core.module.descriptor.Artifact;
3234 import org.apache.ivy.core.module.descriptor.Configuration;
33 import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
3435 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
3536 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
3637 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
38 import org.apache.ivy.core.module.descriptor.License;
3739 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3840 import org.apache.ivy.core.module.id.ModuleRevisionId;
3941 import org.apache.ivy.core.resolve.ResolveData;
4042 import org.apache.ivy.core.resolve.ResolveEngine;
4143 import org.apache.ivy.core.resolve.ResolveOptions;
4244 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
43 import org.apache.ivy.plugins.namespace.NameSpaceHelper;
45 import org.apache.ivy.plugins.circular.CircularDependencyException;
4446 import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
4547 import org.apache.ivy.plugins.parser.ParserSettings;
4648 import org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.PomDependencyDescriptor;
4749 import org.apache.ivy.plugins.parser.m2.PomReader.PomDependencyData;
4850 import org.apache.ivy.plugins.parser.m2.PomReader.PomDependencyMgtElement;
51 import org.apache.ivy.plugins.parser.m2.PomReader.PomPluginElement;
52 import org.apache.ivy.plugins.parser.m2.PomReader.PomProfileElement;
4953 import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
5054 import org.apache.ivy.plugins.repository.Resource;
5155 import org.apache.ivy.plugins.repository.url.URLResource;
5357 import org.apache.ivy.util.Message;
5458 import org.xml.sax.SAXException;
5559
60 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
61 import static org.apache.ivy.plugins.namespace.NameSpaceHelper.toSystem;
62 import static org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.MAVEN2_CONFIGURATIONS;
63 import static org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.extractPomProperties;
64 import static org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.getDependencyManagements;
65 import static org.apache.ivy.plugins.parser.m2.PomModuleDescriptorBuilder.getPlugins;
66
5667 /**
5768 * A parser for Maven 2 POM.
5869 * <p>
59 * The configurations used in the generated module descriptor mimics the behavior defined by maven 2
60 * scopes, as documented here:<br/>
61 * http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html The
62 * PomModuleDescriptorParser use a PomDomReader to read the pom, and the PomModuleDescriptorBuilder
63 * to write the ivy module descriptor using the info read by the PomDomReader.
70 * The configurations used in the generated module descriptor mimics the behavior defined by Maven 2
71 * scopes, as documented <a href=
72 * "https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html">here</a>.
73 * The PomModuleDescriptorParser use a PomDomReader to read the pom, and the
74 * PomModuleDescriptorBuilder to write the ivy module descriptor using the info read by the
75 * PomDomReader.
76 * </p>
6477 */
6578 public final class PomModuleDescriptorParser implements ModuleDescriptorParser {
6679
6780 private static final PomModuleDescriptorParser INSTANCE = new PomModuleDescriptorParser();
81
82 private static final String PARENT_MAP_KEY = PomModuleDescriptorParser.class.getName() + ".parentMap";
6883
6984 public static PomModuleDescriptorParser getInstance() {
7085 return INSTANCE;
114129 ivySettings);
115130
116131 try {
132 final IvyContext ivyContext = IvyContext.pushNewCopyContext();
133 Set<ModuleRevisionId> parents = ivyContext.get(PARENT_MAP_KEY);
134 if (parents == null) {
135 parents = new LinkedHashSet<>();
136 ivyContext.set(PARENT_MAP_KEY, parents);
137 }
138
117139 PomReader domReader = new PomReader(descriptorURL, res);
118140 domReader.setProperty("parent.version", domReader.getParentVersion());
119141 domReader.setProperty("parent.groupId", domReader.getParentGroupId());
120142 domReader.setProperty("project.parent.version", domReader.getParentVersion());
121143 domReader.setProperty("project.parent.groupId", domReader.getParentGroupId());
122144
123 Map pomProperties = domReader.getPomProperties();
124 for (Iterator iter = pomProperties.entrySet().iterator(); iter.hasNext();) {
125 Map.Entry prop = (Map.Entry) iter.next();
126 domReader.setProperty((String) prop.getKey(), (String) prop.getValue());
127 mdBuilder.addProperty((String) prop.getKey(), (String) prop.getValue());
145 Message.debug("parent.groupId: " + domReader.getParentGroupId());
146 Message.debug("parent.artifactId: " + domReader.getParentArtifactId());
147 Message.debug("parent.version: " + domReader.getParentVersion());
148
149 for (final Map.Entry<String, String> prop : domReader.getPomProperties().entrySet()) {
150 domReader.setProperty(prop.getKey(), prop.getValue());
151 mdBuilder.addProperty(prop.getKey(), prop.getValue());
152 }
153 final List<PomProfileElement> activeProfiles = new ArrayList<>();
154 // add profile specific properties
155 for (final PomProfileElement profile : domReader.getProfiles()) {
156 if (!profile.isActive()) {
157 continue;
158 }
159 // keep track of this active profile for later use
160 activeProfiles.add(profile);
161
162 final Map<String, String> profileProps = profile.getProfileProperties();
163 if (profileProps.isEmpty()) {
164 continue;
165 }
166 for (final Map.Entry<String, String> entry : profileProps.entrySet()) {
167 domReader.setProperty(entry.getKey(), entry.getValue());
168 mdBuilder.addProperty(entry.getKey(), entry.getValue());
169 }
128170 }
129171
130172 ModuleDescriptor parentDescr = null;
134176 ModuleRevisionId parentModRevID = ModuleRevisionId.newInstance(
135177 domReader.getParentGroupId(), domReader.getParentArtifactId(),
136178 domReader.getParentVersion());
137 ResolvedModuleRevision parentModule = parseOtherPom(ivySettings, parentModRevID);
138 if (parentModule != null) {
139 parentDescr = parentModule.getDescriptor();
179
180 // check for cycles
181 if (parents.contains(parentModRevID)) {
182 throw new CircularDependencyException(parents);
140183 } else {
141 throw new IOException("Impossible to load parent for " + res.getName() + "."
142 + " Parent=" + parentModRevID);
143 }
184 parents.add(parentModRevID);
185 }
186
187 final ResolvedModuleRevision parentModule = parseOtherPom(ivySettings, parentModRevID, true);
188 if (parentModule == null) {
189 throw new IOException("Impossible to load parent for " + res.getName()
190 + ". Parent=" + parentModRevID);
191 }
192 parentDescr = parentModule.getDescriptor();
144193 if (parentDescr != null) {
145 Map parentPomProps = PomModuleDescriptorBuilder
146 .extractPomProperties(parentDescr.getExtraInfos());
147 for (Iterator iter = parentPomProps.entrySet().iterator(); iter.hasNext();) {
148 Map.Entry prop = (Map.Entry) iter.next();
149 domReader.setProperty((String) prop.getKey(), (String) prop.getValue());
194 for (Map.Entry<String, String> prop
195 : extractPomProperties(parentDescr.getExtraInfos()).entrySet()) {
196 domReader.setProperty(prop.getKey(), prop.getValue());
150197 }
151198 }
152199 }
158205
159206 mdBuilder.setHomePage(domReader.getHomePage());
160207 mdBuilder.setDescription(domReader.getDescription());
161 mdBuilder.setLicenses(domReader.getLicenses());
208 // if this module doesn't have an explicit license, use the parent's license (if any)
209 final License[] licenses = domReader.getLicenses();
210 if (licenses != null && licenses.length > 0) {
211 mdBuilder.setLicenses(licenses);
212 } else if (parentDescr != null) {
213 mdBuilder.setLicenses(parentDescr.getLicenses());
214 }
162215
163216 ModuleRevisionId relocation = domReader.getRelocation();
164217
165218 if (relocation != null) {
166 if (groupId != null && artifactId != null
167 && artifactId.equals(relocation.getName())
219 if (groupId != null && artifactId != null && artifactId.equals(relocation.getName())
168220 && groupId.equals(relocation.getOrganisation())) {
169221 Message.error("Relocation to an other version number not supported in ivy : "
170222 + mdBuilder.getModuleDescriptor().getModuleRevisionId()
171223 + " relocated to " + relocation
172224 + ". Please update your dependency to directly use the right version.");
173225 Message.warn("Resolution will only pick dependencies of the relocated element."
174 + " Artefact and other metadata will be ignored.");
175 ResolvedModuleRevision relocatedModule = parseOtherPom(ivySettings, relocation);
226 + " Artifact and other metadata will be ignored.");
227 ResolvedModuleRevision relocatedModule = parseOtherPom(ivySettings, relocation, false);
176228 if (relocatedModule == null) {
177 throw new ParseException("impossible to load module " + relocation
178 + " to which "
179 + mdBuilder.getModuleDescriptor().getModuleRevisionId()
180 + " has been relocated", 0);
181 }
182 DependencyDescriptor[] dds = relocatedModule.getDescriptor().getDependencies();
183 for (int i = 0; i < dds.length; i++) {
184 mdBuilder.addDependency(dds[i]);
229 throw new ParseException(
230 "impossible to load module " + relocation + " to which "
231 + mdBuilder.getModuleDescriptor().getModuleRevisionId()
232 + " has been relocated",
233 0);
234 }
235 for (DependencyDescriptor dd : relocatedModule.getDescriptor()
236 .getDependencies()) {
237 mdBuilder.addDependency(dd);
185238 }
186239 } else {
187 Message.info(mdBuilder.getModuleDescriptor().getModuleRevisionId()
188 + " is relocated to " + relocation
189 + ". Please update your dependencies.");
240 Message.info(
241 mdBuilder.getModuleDescriptor().getModuleRevisionId() + " is relocated to "
242 + relocation + ". Please update your dependencies.");
190243 Message.verbose("Relocated module will be considered as a dependency");
191244 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(
192245 mdBuilder.getModuleDescriptor(), relocation, true, false, true);
193246 /* Map all public dependencies */
194 Configuration[] m2Confs = PomModuleDescriptorBuilder.MAVEN2_CONFIGURATIONS;
195 for (int i = 0; i < m2Confs.length; i++) {
196 if (Visibility.PUBLIC.equals(m2Confs[i].getVisibility())) {
197 dd.addDependencyConfiguration(m2Confs[i].getName(),
198 m2Confs[i].getName());
247 for (Configuration m2Conf : MAVEN2_CONFIGURATIONS) {
248 if (PUBLIC.equals(m2Conf.getVisibility())) {
249 dd.addDependencyConfiguration(m2Conf.getName(), m2Conf.getName());
199250 }
200251 }
201252 mdBuilder.addDependency(dd);
215266 mdBuilder.addExtraInfos(parentDescr.getExtraInfos());
216267
217268 // add dependency management info from parent
218 List depMgt = PomModuleDescriptorBuilder.getDependencyManagements(parentDescr);
219 for (Iterator it = depMgt.iterator(); it.hasNext();) {
220 PomDependencyMgt dep = (PomDependencyMgt) it.next();
269 for (PomDependencyMgt dep : getDependencyManagements(parentDescr)) {
221270 if (dep instanceof PomDependencyMgtElement) {
222271 dep = domReader.new PomDependencyMgtElement(
223272 (PomDependencyMgtElement) dep);
226275 }
227276
228277 // add plugins from parent
229 List /* <PomDependencyMgt> */plugins = PomModuleDescriptorBuilder
230 .getPlugins(parentDescr);
231 for (Iterator it = plugins.iterator(); it.hasNext();) {
232 mdBuilder.addPlugin((PomDependencyMgt) it.next());
233 }
234 }
235
236 for (Iterator it = domReader.getDependencyMgt().iterator(); it.hasNext();) {
237 PomDependencyMgt dep = (PomDependencyMgt) it.next();
238 if ("import".equals(dep.getScope())) {
239 ModuleRevisionId importModRevID = ModuleRevisionId.newInstance(
240 dep.getGroupId(), dep.getArtifactId(), dep.getVersion());
241 ResolvedModuleRevision importModule = parseOtherPom(ivySettings,
242 importModRevID);
243 if (importModule != null) {
244 ModuleDescriptor importDescr = importModule.getDescriptor();
245
246 // add dependency management info from imported module
247 List depMgt = PomModuleDescriptorBuilder
248 .getDependencyManagements(importDescr);
249 for (Iterator it2 = depMgt.iterator(); it2.hasNext();) {
250 PomDependencyMgt importedDepMgt = (PomDependencyMgt) it2.next();
251 mdBuilder.addDependencyMgt(new DefaultPomDependencyMgt(
252 importedDepMgt.getGroupId(),
253 importedDepMgt.getArtifactId(),
254 importedDepMgt.getVersion(), importedDepMgt.getScope(),
255 importedDepMgt.getExcludedModules()));
256 }
257 } else {
258 throw new IOException("Impossible to import module for "
259 + res.getName() + "." + " Import=" + importModRevID);
260 }
261
262 } else {
263 mdBuilder.addDependencyMgt(dep);
264 }
265 }
266
267 for (Iterator it = domReader.getDependencies().iterator(); it.hasNext();) {
268 PomReader.PomDependencyData dep = (PomReader.PomDependencyData) it.next();
278 for (PomDependencyMgt pomDependencyMgt : getPlugins(parentDescr)) {
279 mdBuilder.addPlugin(pomDependencyMgt);
280 }
281 }
282
283 for (PomDependencyMgt dep : domReader.getDependencyMgt()) {
284 addTo(mdBuilder, dep, ivySettings);
285 }
286 for (PomDependencyData dep : domReader.getDependencies()) {
269287 mdBuilder.addDependency(res, dep);
270288 }
271289
290 for (PomPluginElement plugin : domReader.getPlugins()) {
291 mdBuilder.addPlugin(plugin);
292 }
293
294 // consult active profiles:
295 for (final PomProfileElement activeProfile : activeProfiles) {
296 for (PomDependencyMgt dep : activeProfile.getDependencyMgt()) {
297 addTo(mdBuilder, dep, ivySettings);
298 }
299 for (PomDependencyData dep : activeProfile.getDependencies()) {
300 mdBuilder.addDependency(res, dep);
301 }
302 for (PomPluginElement plugin : activeProfile.getPlugins()) {
303 mdBuilder.addPlugin(plugin);
304 }
305 }
306
272307 if (parentDescr != null) {
273 for (int i = 0; i < parentDescr.getDependencies().length; i++) {
274 DependencyDescriptor descriptor = parentDescr.getDependencies()[i];
308 for (DependencyDescriptor descriptor : parentDescr.getDependencies()) {
275309 if (descriptor instanceof PomDependencyDescriptor) {
276310 PomDependencyData parentDep = ((PomDependencyDescriptor) descriptor)
277311 .getPomDependencyData();
283317 }
284318 }
285319
286 for (Iterator it = domReader.getPlugins().iterator(); it.hasNext();) {
287 PomReader.PomPluginElement plugin = (PomReader.PomPluginElement) it.next();
288 mdBuilder.addPlugin(plugin);
289 }
290
291320 mdBuilder.addMainArtifact(artifactId, domReader.getPackaging());
292321
293322 addSourcesAndJavadocArtifactsIfPresent(mdBuilder, ivySettings);
294323 }
295324 } catch (SAXException e) {
296325 throw newParserException(e);
326 } finally {
327 IvyContext.popContext();
297328 }
298329
299330 return mdBuilder.getModuleDescriptor();
331 }
332
333 private void addTo(PomModuleDescriptorBuilder mdBuilder, PomDependencyMgt dep,
334 ParserSettings ivySettings) throws ParseException, IOException {
335 if ("import".equals(dep.getScope())) {
336 // In Maven, "import" scope semantics are equivalent to getting (only) the
337 // dependency management section of the imported module, into the current
338 // module, so that those "managed dependency versions" are usable/applicable
339 // in the current module's dependencies
340 ModuleRevisionId importModRevID = ModuleRevisionId.newInstance(dep.getGroupId(),
341 dep.getArtifactId(), dep.getVersion());
342 ResolvedModuleRevision importModule = parseOtherPom(ivySettings, importModRevID, false);
343 if (importModule == null) {
344 throw new IOException("Impossible to import module for "
345 + mdBuilder.getModuleDescriptor().getResource().getName() + ". Import="
346 + importModRevID);
347 }
348 ModuleDescriptor importDescr = importModule.getDescriptor();
349
350 // add dependency management info from imported module
351 for (PomDependencyMgt importedDepMgt : getDependencyManagements(importDescr)) {
352 mdBuilder.addDependencyMgt(new DefaultPomDependencyMgt(importedDepMgt.getGroupId(),
353 importedDepMgt.getArtifactId(), importedDepMgt.getVersion(),
354 importedDepMgt.getScope(), importedDepMgt.getExcludedModules()));
355 }
356 } else {
357 mdBuilder.addDependencyMgt(dep);
358 }
359
300360 }
301361
302362 private void addSourcesAndJavadocArtifactsIfPresent(PomModuleDescriptorBuilder mdBuilder,
305365 // no main artifact in pom, we don't need to search for meta artifacts
306366 return;
307367 }
368
369 boolean sourcesLookup = !"false"
370 .equals(ivySettings.getVariable("ivy.maven.lookup.sources"));
371 boolean javadocLookup = !"false"
372 .equals(ivySettings.getVariable("ivy.maven.lookup.javadoc"));
373 if (!sourcesLookup && !javadocLookup) {
374 Message.debug("Sources and javadocs lookup disabled");
375 return;
376 }
377
308378 ModuleDescriptor md = mdBuilder.getModuleDescriptor();
309379 ModuleRevisionId mrid = md.getModuleRevisionId();
310380 DependencyResolver resolver = ivySettings.getResolver(mrid);
311381
312382 if (resolver == null) {
313 Message.debug("no resolver found for " + mrid
314 + ": no source or javadoc artifact lookup");
383 Message.debug(
384 "no resolver found for " + mrid + ": no source or javadoc artifact lookup");
315385 } else {
316386 ArtifactOrigin mainArtifact = resolver.locate(mdBuilder.getMainArtifact());
317387
318388 if (!ArtifactOrigin.isUnknown(mainArtifact)) {
319389 String mainArtifactLocation = mainArtifact.getLocation();
320390
321 ArtifactOrigin sourceArtifact = resolver.locate(mdBuilder.getSourceArtifact());
322 if (!ArtifactOrigin.isUnknown(sourceArtifact)
323 && !sourceArtifact.getLocation().equals(mainArtifactLocation)) {
324 Message.debug("source artifact found for " + mrid);
325 mdBuilder.addSourceArtifact();
391 if (sourcesLookup) {
392 ArtifactOrigin sourceArtifact = resolver.locate(mdBuilder.getSourceArtifact());
393 if (!ArtifactOrigin.isUnknown(sourceArtifact)
394 && !sourceArtifact.getLocation().equals(mainArtifactLocation)) {
395 Message.debug("source artifact found for " + mrid);
396 mdBuilder.addSourceArtifact();
397 } else {
398 // it seems that sometimes the 'src' classifier is used instead of 'sources'
399 // Cfr. IVY-1138
400 ArtifactOrigin srcArtifact = resolver.locate(mdBuilder.getSrcArtifact());
401 if (!ArtifactOrigin.isUnknown(srcArtifact)
402 && !srcArtifact.getLocation().equals(mainArtifactLocation)) {
403 Message.debug("source artifact found for " + mrid);
404 mdBuilder.addSrcArtifact();
405 } else {
406 Message.debug("no source artifact found for " + mrid);
407 }
408 }
326409 } else {
327 // it seems that sometimes the 'src' classifier is used instead of 'sources'
328 // Cfr. IVY-1138
329 ArtifactOrigin srcArtifact = resolver.locate(mdBuilder.getSrcArtifact());
330 if (!ArtifactOrigin.isUnknown(srcArtifact)
331 && !srcArtifact.getLocation().equals(mainArtifactLocation)) {
332 Message.debug("source artifact found for " + mrid);
333 mdBuilder.addSrcArtifact();
410 Message.debug("sources lookup disabled");
411 }
412
413 if (javadocLookup) {
414 ArtifactOrigin javadocArtifact = resolver
415 .locate(mdBuilder.getJavadocArtifact());
416 if (!ArtifactOrigin.isUnknown(javadocArtifact)
417 && !javadocArtifact.getLocation().equals(mainArtifactLocation)) {
418 Message.debug("javadoc artifact found for " + mrid);
419 mdBuilder.addJavadocArtifact();
334420 } else {
335 Message.debug("no source artifact found for " + mrid);
336 }
337 }
338 ArtifactOrigin javadocArtifact = resolver.locate(mdBuilder.getJavadocArtifact());
339 if (!ArtifactOrigin.isUnknown(javadocArtifact)
340 && !javadocArtifact.getLocation().equals(mainArtifactLocation)) {
341 Message.debug("javadoc artifact found for " + mrid);
342 mdBuilder.addJavadocArtifact();
421 Message.debug("no javadoc artifact found for " + mrid);
422 }
343423 } else {
344 Message.debug("no javadoc artifact found for " + mrid);
345 }
346 }
347 }
348 }
349
350 private ResolvedModuleRevision parseOtherPom(ParserSettings ivySettings,
351 ModuleRevisionId parentModRevID) throws ParseException {
352 DependencyDescriptor dd = new DefaultDependencyDescriptor(parentModRevID, true);
353 ResolveData data = IvyContext.getContext().getResolveData();
354 if (data == null) {
355 ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
356 ResolveOptions options = new ResolveOptions();
357 options.setDownload(false);
358 data = new ResolveData(engine, options);
359 }
360
361 DependencyResolver resolver = ivySettings.getResolver(parentModRevID);
362 if (resolver == null) {
363 // TODO: Throw exception here?
364 return null;
365 } else {
366 dd = NameSpaceHelper.toSystem(dd, ivySettings.getContextNamespace());
367 ResolvedModuleRevision otherModule = resolver.getDependency(dd, data);
368 return otherModule;
424 Message.debug("javadocs lookup disabled");
425 }
426 }
427 }
428 }
429
430 private ResolvedModuleRevision parseOtherPom(final ParserSettings ivySettings,
431 final ModuleRevisionId parentModRevID, final boolean isParentPom) throws ParseException {
432
433 Set<ModuleRevisionId> previousParents = null;
434 if (!isParentPom) {
435 // IVY-1588: we "reset" the parent tracking, since the parent tracking should only be
436 // non-null when we are parsing a parent pom.
437 previousParents = IvyContext.getContext().get(PARENT_MAP_KEY);
438 if (previousParents != null) {
439 IvyContext.getContext().set(PARENT_MAP_KEY, null);
440 }
441 }
442 try {
443 DependencyDescriptor dd = new DefaultDependencyDescriptor(parentModRevID, true);
444 ResolveData data = IvyContext.getContext().getResolveData();
445 if (data == null) {
446 ResolveEngine engine = IvyContext.getContext().getIvy().getResolveEngine();
447 ResolveOptions options = new ResolveOptions();
448 options.setDownload(false);
449 data = new ResolveData(engine, options);
450 }
451
452 DependencyResolver resolver = ivySettings.getResolver(parentModRevID);
453 if (resolver == null) {
454 // TODO: Throw exception here?
455 return null;
456 }
457 dd = toSystem(dd, ivySettings.getContextNamespace());
458 return resolver.getDependency(dd, data);
459 } finally {
460 if (!isParentPom) {
461 // switch back to the previous state of the parent tracking
462 IvyContext.getContext().set(PARENT_MAP_KEY, previousParents);
463 }
369464 }
370465 }
371466
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.io.LineNumberReader;
2525 import java.io.OutputStreamWriter;
2626 import java.io.PrintWriter;
27 import java.nio.charset.StandardCharsets;
2728 import java.util.ArrayList;
2829 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.LinkedHashMap;
3031 import java.util.List;
3132 import java.util.Map;
3233
4546 import org.apache.ivy.plugins.parser.m2.PomWriterOptions.ExtraDependency;
4647 import org.apache.ivy.util.ConfigurationUtils;
4748
49 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
50
4851 public final class PomModuleDescriptorWriter {
4952
5053 private static final String SKIP_LINE = "SKIP_LINE";
5154
55 @SuppressWarnings("serial")
5256 private static final ConfigurationScopeMapping DEFAULT_MAPPING = new ConfigurationScopeMapping(
53 new HashMap() {
57 new LinkedHashMap<String, String>() {
5458 {
5559 put("compile", "compile");
5660 put("runtime", "runtime");
7882 output.getParentFile().mkdirs();
7983 }
8084 PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output),
81 "UTF-8"));
85 StandardCharsets.UTF_8));
8286 try {
8387 IvySettings settings = IvyContext.getContext().getSettings();
8488 IvyVariableContainer variables = new IvyVariableContainerWrapper(
113117 String line = in.readLine();
114118 while (line != null) {
115119 line = IvyPatternHelper.substituteVariables(line, variables);
116 if (line.indexOf(SKIP_LINE) != -1) {
120 if (line.contains(SKIP_LINE)) {
117121 // skip this line
118122 line = in.readLine();
119123 continue;
120124 }
121125
122 if (line.trim().length() == 0) {
126 if (line.trim().isEmpty()) {
123127 // empty line
124128 out.println(line);
125129 line = in.readLine();
129133 lastIndent = indent;
130134 indent = line.indexOf('<');
131135
132 if (!dependenciesPrinted && line.indexOf("</dependencies>") != -1) {
136 if (!dependenciesPrinted && line.contains("</dependencies>")) {
133137 printDependencies(md, out, options, indent, false);
134138 dependenciesPrinted = true;
135139 }
136140
137 if (!dependenciesPrinted && line.indexOf("</project>") != -1) {
141 if (!dependenciesPrinted && line.contains("</project>")) {
138142 printDependencies(md, out, options, lastIndent, true);
139143 dependenciesPrinted = true;
140144 }
177181 }
178182 if (options.getDescription() != null) {
179183 variables.setVariable("ivy.pom.description", options.getDescription(), true);
184 } else if (!isNullOrEmpty(md.getDescription())) {
185 variables.setVariable("ivy.pom.description", md.getDescription(), true);
180186 }
181187 if (md.getHomePage() != null) {
182188 variables.setVariable("ivy.pom.url", md.getHomePage(), true);
187193 * Returns the first artifact with the correct name and without a classifier.
188194 */
189195 private static Artifact findArtifact(ModuleDescriptor md, String artifactName) {
190 Artifact[] artifacts = md.getAllArtifacts();
191 for (int i = 0; i < artifacts.length; i++) {
192 if (artifacts[i].getName().equals(artifactName)
193 && artifacts[i].getAttribute("classifier") == null) {
194 return artifacts[i];
196 for (Artifact artifact : md.getAllArtifacts()) {
197 if (artifact.getName().equals(artifactName)
198 && artifact.getAttribute("classifier") == null) {
199 return artifact;
195200 }
196201 }
197202
206211
207212 private static void printDependencies(ModuleDescriptor md, PrintWriter out,
208213 PomWriterOptions options, int indent, boolean printDependencies) {
209 List extraDeps = options.getExtraDependencies();
214 List<ExtraDependency> extraDeps = options.getExtraDependencies();
210215 DependencyDescriptor[] dds = getDependencies(md, options);
211216
212217 if (!extraDeps.isEmpty() || (dds.length > 0)) {
216221 }
217222
218223 // print the extra dependencies first
219 for (Iterator it = extraDeps.iterator(); it.hasNext();) {
220 PomWriterOptions.ExtraDependency dep = (ExtraDependency) it.next();
224 for (ExtraDependency dep : extraDeps) {
221225 String groupId = dep.getGroup();
222226 if (groupId == null) {
223227 groupId = md.getModuleRevisionId().getOrganisation();
236240 mapping = DEFAULT_MAPPING;
237241 }
238242
239 for (int i = 0; i < dds.length; i++) {
240 ModuleRevisionId mrid = dds[i].getDependencyRevisionId();
243 for (DependencyDescriptor dd : dds) {
244 ModuleRevisionId mrid = dd.getDependencyRevisionId();
241245 ExcludeRule[] excludes = null;
242 if (dds[i].canExclude()) {
243 excludes = dds[i].getAllExcludeRules();
244 }
245 DependencyArtifactDescriptor[] dads = dds[i].getAllDependencyArtifacts();
246 if (dd.canExclude()) {
247 excludes = dd.getAllExcludeRules();
248 }
249 DependencyArtifactDescriptor[] dads = dd.getAllDependencyArtifacts();
246250 if (dads.length > 0) {
247 for (int j = 0; j < dads.length; j++) {
248 String type = dads[j].getType();
249 String classifier = dads[j].getExtraAttribute("classifier");
250 String scope = mapping.getScope(dds[i].getModuleConfigurations());
251 boolean optional = mapping.isOptional(dds[i].getModuleConfigurations());
251 for (DependencyArtifactDescriptor dad : dads) {
252 String type = dad.getType();
253 String classifier = dad.getExtraAttribute("classifier");
254 String scope = mapping.getScope(dd.getModuleConfigurations());
255 boolean optional = mapping.isOptional(dd.getModuleConfigurations());
252256 printDependency(out, indent, mrid.getOrganisation(), mrid.getName(),
253257 mrid.getRevision(), type, classifier, scope, optional,
254 dds[i].isTransitive(), excludes);
258 dd.isTransitive(), excludes);
255259 }
256260 } else {
257 String scope = mapping.getScope(dds[i].getModuleConfigurations());
258 boolean optional = mapping.isOptional(dds[i].getModuleConfigurations());
261 String scope = mapping.getScope(dd.getModuleConfigurations());
262 boolean optional = mapping.isOptional(dd.getModuleConfigurations());
263 final String classifier = dd.getExtraAttribute("classifier");
259264 printDependency(out, indent, mrid.getOrganisation(), mrid.getName(),
260 mrid.getRevision(), null, null, scope, optional, dds[i].isTransitive(),
265 mrid.getRevision(), null, classifier, scope, optional, dd.isTransitive(),
261266 excludes);
262267 }
263268 }
320325 indent(out, indent * 3);
321326 out.println("<exclusions>");
322327
323 for (int i = 0; i < exclusions.length; i++) {
328 for (ExcludeRule exclusion : exclusions) {
324329 indent(out, indent * 4);
325330 out.println("<exclusion>");
326 ExcludeRule rule = exclusions[i];
327331 indent(out, indent * 5);
328 out.println("<groupId>" + rule.getId().getModuleId().getOrganisation() + "</groupId>");
332 out.println(
333 "<groupId>" + exclusion.getId().getModuleId().getOrganisation() + "</groupId>");
329334 indent(out, indent * 5);
330 out.println("<artifactId>" + rule.getId().getModuleId().getName() + "</artifactId>");
335 out.println(
336 "<artifactId>" + exclusion.getId().getModuleId().getName() + "</artifactId>");
331337 indent(out, indent * 4);
332338 out.println("</exclusion>");
333339 }
340346 PomWriterOptions options) {
341347 String[] confs = ConfigurationUtils.replaceWildcards(options.getConfs(), md);
342348
343 List result = new ArrayList();
344 DependencyDescriptor[] dds = md.getDependencies();
345 for (int i = 0; i < dds.length; i++) {
346 String[] depConfs = dds[i].getDependencyConfigurations(confs);
347 if ((depConfs != null) && (depConfs.length > 0)) {
348 result.add(dds[i]);
349 }
350 }
351
352 return (DependencyDescriptor[]) result.toArray(new DependencyDescriptor[result.size()]);
349 List<DependencyDescriptor> result = new ArrayList<>();
350 for (DependencyDescriptor dd : md.getDependencies()) {
351 String[] depConfs = dd.getDependencyConfigurations(confs);
352 if (depConfs != null && depConfs.length > 0) {
353 result.add(dd);
354 }
355 }
356
357 return result.toArray(new DependencyDescriptor[result.size()]);
353358 }
354359
355360 /**
361366
362367 private final IvyVariableContainer variables;
363368
364 private Map localVariables = new HashMap();
369 private Map<String, String> localVariables = new HashMap<>();
365370
366371 private IvyVariableContainerWrapper(IvyVariableContainer variables) {
367372 this.variables = variables;
378383 public String getVariable(String name) {
379384 String result = variables.getVariable(name);
380385 if (result == null) {
381 result = (String) localVariables.get(name);
386 result = localVariables.get(name);
382387 }
383388 return result;
384389 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1515 *
1616 */
1717 package org.apache.ivy.plugins.parser.m2;
18
19 import java.io.BufferedInputStream;
20 import java.io.FilterInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.InputStreamReader;
24 import java.io.LineNumberReader;
25 import java.net.URL;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.LinkedList;
31 import java.util.List;
32 import java.util.Map;
3318
3419 import org.apache.ivy.core.IvyPatternHelper;
3520 import org.apache.ivy.core.module.descriptor.License;
4732 import org.xml.sax.SAXException;
4833 import org.xml.sax.SAXParseException;
4934
35 import java.io.BufferedInputStream;
36 import java.io.File;
37 import java.io.FilterInputStream;
38 import java.io.IOException;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.io.LineNumberReader;
42 import java.net.URL;
43 import java.nio.charset.StandardCharsets;
44 import java.util.ArrayList;
45 import java.util.Collections;
46 import java.util.HashMap;
47 import java.util.LinkedList;
48 import java.util.List;
49 import java.util.Map;
50 import java.util.Properties;
51
5052 /**
5153 * Provides the method to read some data out of the DOM tree of a pom file.
5254 */
5355 public class PomReader {
5456
57 private static final String PROFILES_ELEMENT = "profiles";
58
5559 private static final String PACKAGING = "packaging";
5660
5761 private static final String DEPENDENCY = "dependency";
106110
107111 private static final String TYPE = "type";
108112
109 private HashMap properties = new HashMap();
113 private static final String PROFILE = "profile";
114
115 private final Map<String, String> properties = new HashMap<>();
110116
111117 private final Element projectElement;
112118
113119 private final Element parentElement;
114120
115 public PomReader(URL descriptorURL, Resource res) throws IOException, SAXException {
116 InputStream stream = new AddDTDFilterInputStream(URLHandlerRegistry.getDefault()
117 .openStream(descriptorURL));
121 @SuppressWarnings("deprecation")
122 public PomReader(final URL descriptorURL, final Resource res) throws IOException, SAXException {
123 InputStream stream = new AddDTDFilterInputStream(
124 URLHandlerRegistry.getDefault().openStream(descriptorURL));
118125 InputSource source = new InputSource(stream);
119126 source.setSystemId(XMLHelper.toSystemId(descriptorURL));
120127 try {
121128 Document pomDomDoc = XMLHelper.parseToDom(source, new EntityResolver() {
122129 public InputSource resolveEntity(String publicId, String systemId)
123130 throws SAXException, IOException {
124 if ((systemId != null) && systemId.endsWith("m2-entities.ent")) {
125 return new InputSource(PomReader.class
126 .getResourceAsStream("m2-entities.ent"));
131 if (systemId != null && systemId.endsWith("m2-entities.ent")) {
132 return new InputSource(
133 PomReader.class.getResourceAsStream("m2-entities.ent"));
127134 }
128135 return null;
129136 }
142149 // ignore
143150 }
144151 }
152 // Both environment and system properties take precedence over properties set in
153 // pom.xml. So we pre-populate our properties with the environment and system properties
154 // here
155 for (final Map.Entry<String, String> envEntry : System.getenv().entrySet()) {
156 // Maven let's users use "env." prefix for environment variables
157 this.setProperty("env." + envEntry.getKey(), envEntry.getValue());
158 }
159 // add system properties
160 final Properties sysProps = System.getProperties();
161 for (final String sysProp : sysProps.stringPropertyNames()) {
162 this.setProperty(sysProp, sysProps.getProperty(sysProp));
163 }
145164 }
146165
147166 public boolean hasParent() {
149168 }
150169
151170 /**
152 * Add a property if not yet set and value is not null. This garantee that property keep the
153 * first value that is put on it and that the properties are never null.
171 * Add a property if not yet set and value is not null. This guarantees
172 * that property keeps the first value that is put on it and that the
173 * properties are never null.
174 *
175 * @param prop String
176 * @param val String
154177 */
155178 public void setProperty(String prop, String val) {
156179 if (!properties.containsKey(prop) && val != null) {
208231 }
209232
210233 public String getPackaging() {
211 String val = getFirstChildText(projectElement, PACKAGING);
234 final String val = getFirstChildText(projectElement, PACKAGING);
212235 if (val == null) {
213 val = "jar";
214 }
215 return val;
236 return "jar";
237 }
238 return replaceProps(val);
216239 }
217240
218241 public String getHomePage() {
237260 return new License[0];
238261 }
239262 licenses.normalize();
240 List/* <License> */lics = new ArrayList();
241 for (Iterator it = getAllChilds(licenses).iterator(); it.hasNext();) {
242 Element license = (Element) it.next();
263 List<License> lics = new ArrayList<>();
264 for (Element license : getAllChilds(licenses)) {
243265 if (LICENSE.equals(license.getNodeName())) {
244266 String name = getFirstChildText(license, LICENSE_NAME);
245267 String url = getFirstChildText(license, LICENSE_URL);
246268
247 if ((name == null) && (url == null)) {
269 if (name == null && url == null) {
248270 // move to next license
249271 continue;
250272 }
257279 lics.add(new License(name, url));
258280 }
259281 }
260 return (License[]) lics.toArray(new License[lics.size()]);
282 return lics.toArray(new License[lics.size()]);
261283 }
262284
263285 public ModuleRevisionId getRelocation() {
267289 return null;
268290 } else {
269291 String relocGroupId = getFirstChildText(relocation, GROUP_ID);
292 if (relocGroupId == null) {
293 relocGroupId = getGroupId();
294 }
270295 String relocArtId = getFirstChildText(relocation, ARTIFACT_ID);
296 if (relocArtId == null) {
297 relocArtId = getArtifactId();
298 }
271299 String relocVersion = getFirstChildText(relocation, VERSION);
272 relocGroupId = relocGroupId == null ? getGroupId() : relocGroupId;
273 relocArtId = relocArtId == null ? getArtifactId() : relocArtId;
274 relocVersion = relocVersion == null ? getVersion() : relocVersion;
300 if (relocVersion == null) {
301 relocVersion = getVersion();
302 }
275303 return ModuleRevisionId.newInstance(relocGroupId, relocArtId, relocVersion);
276304 }
277305 }
278306
279 public List /* <PomDependencyData> */getDependencies() {
280 Element dependenciesElement = getFirstChildElement(projectElement, DEPENDENCIES);
281 LinkedList dependencies = new LinkedList();
282 if (dependenciesElement != null) {
283 NodeList childs = dependenciesElement.getChildNodes();
284 for (int i = 0; i < childs.getLength(); i++) {
285 Node node = childs.item(i);
286 if (node instanceof Element && DEPENDENCY.equals(node.getNodeName())) {
287 dependencies.add(new PomDependencyData((Element) node));
288 }
307 public List<PomDependencyData> getDependencies() {
308 return getDependencies(projectElement);
309 }
310
311 private List<PomDependencyData> getDependencies(Element parent) {
312 Element dependenciesElement = getFirstChildElement(parent, DEPENDENCIES);
313 if (dependenciesElement == null) {
314 return Collections.emptyList();
315 }
316 List<PomDependencyData> dependencies = new LinkedList<>();
317 NodeList children = dependenciesElement.getChildNodes();
318 for (int i = 0, sz = children.getLength(); i < sz; i++) {
319 Node node = children.item(i);
320 if (node instanceof Element && DEPENDENCY.equals(node.getNodeName())) {
321 dependencies.add(new PomDependencyData((Element) node));
289322 }
290323 }
291324 return dependencies;
292325 }
293326
294 public List /* <PomDependencyMgt> */getDependencyMgt() {
295 Element dependenciesElement = getFirstChildElement(projectElement, DEPENDENCY_MGT);
296 dependenciesElement = getFirstChildElement(dependenciesElement, DEPENDENCIES);
297 LinkedList dependencies = new LinkedList();
298 if (dependenciesElement != null) {
299 NodeList childs = dependenciesElement.getChildNodes();
300 for (int i = 0; i < childs.getLength(); i++) {
301 Node node = childs.item(i);
302 if (node instanceof Element && DEPENDENCY.equals(node.getNodeName())) {
303 dependencies.add(new PomDependencyMgtElement((Element) node));
304 }
327 public List<PomDependencyMgt> getDependencyMgt() {
328 return getDependencyMgt(projectElement);
329 }
330
331 private List<PomDependencyMgt> getDependencyMgt(Element parent) {
332 Element dependenciesElement = getFirstChildElement(
333 getFirstChildElement(parent, DEPENDENCY_MGT), DEPENDENCIES);
334 if (dependenciesElement == null) {
335 return Collections.emptyList();
336 }
337 List<PomDependencyMgt> dependencies = new LinkedList<>();
338 NodeList children = dependenciesElement.getChildNodes();
339 for (int i = 0, sz = children.getLength(); i < sz; i++) {
340 Node node = children.item(i);
341 if (node instanceof Element && DEPENDENCY.equals(node.getNodeName())) {
342 dependencies.add(new PomDependencyMgtElement((Element) node));
305343 }
306344 }
307345 return dependencies;
346 }
347
348 public List<PomProfileElement> getProfiles() {
349 Element profilesElement = getFirstChildElement(projectElement, PROFILES_ELEMENT);
350 if (profilesElement == null) {
351 return Collections.emptyList();
352 }
353 List<PomProfileElement> result = new LinkedList<>();
354 NodeList children = profilesElement.getChildNodes();
355 for (int i = 0, sz = children.getLength(); i < sz; i++) {
356 Node node = children.item(i);
357 if (node instanceof Element && PROFILE.equals(node.getNodeName())) {
358 result.add(new PomProfileElement((Element) node));
359 }
360 }
361 return result;
308362 }
309363
310364 public class PomDependencyMgtElement implements PomDependencyMgt {
320374
321375 /*
322376 * (non-Javadoc)
323 *
377 *
324378 * @see org.apache.ivy.plugins.parser.m2.PomDependencyMgt#getGroupId()
325379 */
326380 public String getGroupId() {
330384
331385 /*
332386 * (non-Javadoc)
333 *
387 *
334388 * @see org.apache.ivy.plugins.parser.m2.PomDependencyMgt#getArtifaceId()
335389 */
336390 public String getArtifactId() {
340394
341395 /*
342396 * (non-Javadoc)
343 *
397 *
344398 * @see org.apache.ivy.plugins.parser.m2.PomDependencyMgt#getVersion()
345399 */
346400 public String getVersion() {
353407 return replaceProps(val);
354408 }
355409
356 public List /* <ModuleId> */getExcludedModules() {
410 public List<ModuleId> getExcludedModules() {
357411 Element exclusionsElement = getFirstChildElement(depElement, EXCLUSIONS);
358 LinkedList exclusions = new LinkedList();
359 if (exclusionsElement != null) {
360 NodeList childs = exclusionsElement.getChildNodes();
361 for (int i = 0; i < childs.getLength(); i++) {
362 Node node = childs.item(i);
363 if (node instanceof Element && EXCLUSION.equals(node.getNodeName())) {
364 String groupId = getFirstChildText((Element) node, GROUP_ID);
365 String artifactId = getFirstChildText((Element) node, ARTIFACT_ID);
366 if ((groupId != null) && (artifactId != null)) {
367 exclusions.add(ModuleId.newInstance(groupId, artifactId));
368 }
412 if (exclusionsElement == null) {
413 return Collections.emptyList();
414 }
415 List<ModuleId> exclusions = new LinkedList<>();
416 NodeList children = exclusionsElement.getChildNodes();
417 for (int i = 0, sz = children.getLength(); i < sz; i++) {
418 Node node = children.item(i);
419 if (node instanceof Element && EXCLUSION.equals(node.getNodeName())) {
420 String groupId = getFirstChildText((Element) node, GROUP_ID);
421 String artifactId = getFirstChildText((Element) node, ARTIFACT_ID);
422 if (groupId != null && artifactId != null) {
423 exclusions.add(ModuleId.newInstance(groupId, artifactId));
369424 }
370425 }
371426 }
373428 }
374429 }
375430
376 public List /* <PomPluginElement> */getPlugins() {
377 LinkedList plugins = new LinkedList();
378
379 Element buildElement = getFirstChildElement(projectElement, "build");
380 if (buildElement == null) {
381 return plugins;
382 }
383
431 public List<PomPluginElement> getPlugins() {
432 return getPlugins(projectElement);
433 }
434
435 private List<PomPluginElement> getPlugins(Element parent) {
436 Element buildElement = getFirstChildElement(parent, "build");
384437 Element pluginsElement = getFirstChildElement(buildElement, PLUGINS);
385 if (pluginsElement != null) {
386 NodeList childs = pluginsElement.getChildNodes();
387 for (int i = 0; i < childs.getLength(); i++) {
388 Node node = childs.item(i);
389 if (node instanceof Element && PLUGIN.equals(node.getNodeName())) {
390 plugins.add(new PomPluginElement((Element) node));
391 }
438
439 if (pluginsElement == null) {
440 return Collections.emptyList();
441 }
442 NodeList children = pluginsElement.getChildNodes();
443 List<PomPluginElement> plugins = new LinkedList<>();
444 for (int i = 0; i < children.getLength(); i++) {
445 Node node = children.item(i);
446 if (node instanceof Element && PLUGIN.equals(node.getNodeName())) {
447 plugins.add(new PomPluginElement((Element) node));
392448 }
393449 }
394450 return plugins;
451 }
452
453 private static Map<String, String> getProperties(final Element parent) {
454 final Element propsEl = getFirstChildElement(parent, PROPERTIES);
455 if (propsEl == null) {
456 return Collections.emptyMap();
457 }
458 propsEl.normalize();
459 final Map<String, String> props = new HashMap<>();
460 for (final Element prop : getAllChilds(propsEl)) {
461 props.put(prop.getNodeName(), getTextContent(prop));
462 }
463 return props;
395464 }
396465
397466 public class PomPluginElement implements PomDependencyMgt {
420489 return null; // not used
421490 }
422491
423 public List /* <ModuleId> */getExcludedModules() {
424 return Collections.EMPTY_LIST; // probably not used?
492 public List<ModuleId> getExcludedModules() {
493 return Collections.emptyList(); // probably not used?
425494 }
426495 }
427496
437506 this.depElement = depElement;
438507 }
439508
509 @Override
440510 public String getScope() {
441511 String val = getFirstChildText(depElement, SCOPE);
442 return replaceProps(val);
512 return emptyIsNull(replaceProps(val));
443513 }
444514
445515 public String getClassifier() {
446516 String val = getFirstChildText(depElement, CLASSIFIER);
447 return replaceProps(val);
517 return emptyIsNull(replaceProps(val));
448518 }
449519
450520 public String getType() {
451521 String val = getFirstChildText(depElement, TYPE);
452 return replaceProps(val);
522 return emptyIsNull(replaceProps(val));
453523 }
454524
455525 public boolean isOptional() {
456 Element e = getFirstChildElement(depElement, OPTIONAL);
457 return (e != null) && "true".equalsIgnoreCase(getTextContent(e));
458 }
459
526 return Boolean.parseBoolean(getFirstChildText(depElement, OPTIONAL));
527 }
528
529 /**
530 * We return null where certain elements within a pom don't have a value specified.
531 * For example, there are pom.xml out there which just use "<classifier/>" in the dependencies.
532 * (dependencies in org.seleniumhq.selenium:selenium-java:3.141.59 are one such example)
533 * We do this so that callers of such elements don't have to keep repeating checks for empty value.
534 * For us an empty value, for many of such elements, is really the same as that element not being specified
535 *
536 * @param val The value to check
537 * @return
538 */
539 private String emptyIsNull(final String val) {
540 if (val == null) {
541 return null;
542 }
543 return val.equals("") ? null : val;
544 }
545 }
546
547 public class PomProfileElement {
548
549 private static final String VALUE = "value";
550
551 private static final String NAME = "name";
552
553 private static final String PROPERTY = "property";
554
555 private static final String ID_ELEMENT = "id";
556
557 private static final String ACTIVATION_ELEMENT = "activation";
558
559 private static final String ACTIVE_BY_DEFAULT_ELEMENT = "activeByDefault";
560
561 private static final String OS = "os";
562
563 private static final String FAMILY = "family";
564
565 private static final String VERSION = "version";
566
567 private static final String ARCH = "arch";
568
569 private static final String FILE = "file";
570
571 private static final String MISSING = "missing";
572
573 private static final String EXISTS = "exists";
574
575 private static final String JDK = "jdk";
576
577 private final Element profileElement;
578
579 PomProfileElement(Element profileElement) {
580 this.profileElement = profileElement;
581 }
582
583 public String getId() {
584 return getFirstChildText(profileElement, ID_ELEMENT);
585 }
586
587 public boolean isActive() {
588 return isActiveByDefault() || isActivatedByProperty()
589 || isActiveByOS() || isActiveByJDK() || isActiveByFile();
590 }
591
592 public boolean isActiveByDefault() {
593 Element activation = getFirstChildElement(profileElement, ACTIVATION_ELEMENT);
594 return Boolean.parseBoolean(getFirstChildText(activation, ACTIVE_BY_DEFAULT_ELEMENT));
595 }
596
597 public boolean isActiveByOS() {
598 final Element activation = getFirstChildElement(profileElement, ACTIVATION_ELEMENT);
599 if (activation == null) {
600 return false;
601 }
602 final Element osActivation = getFirstChildElement(activation, OS);
603 if (osActivation == null) {
604 return false;
605 }
606 final String actualOS = System.getProperty("os.name");
607 final String expectedOSName = getFirstChildText(osActivation, NAME);
608 if (expectedOSName != null && !actualOS.equals(expectedOSName.trim())) {
609 // os name is specified but doesn't match
610 return false;
611 }
612 final String expectedOSFamily = getFirstChildText(osActivation, FAMILY);
613 if (expectedOSFamily != null && !actualOS.contains(expectedOSFamily.trim())) {
614 // os family is specified but doesn't match
615 return false;
616 }
617 final String expectedOSArch = getFirstChildText(osActivation, ARCH);
618 if (expectedOSArch != null && !System.getProperty("os.arch").equals(expectedOSArch.trim())) {
619 // os arch is specified but doesn't match
620 return false;
621 }
622 final String expectedOSVersion = getFirstChildText(osActivation, VERSION);
623 if (expectedOSVersion != null && !System.getProperty("os.version").equals(expectedOSVersion.trim())) {
624 // os version is specified but doesn't match
625 return false;
626 }
627 // reaching here implies that either no OS match rules were specified or
628 // all of the OS rules that were specified were matched. So we just check to see
629 // if any rules were specified at all, in which case, we consider the profile to be activated
630 // by the OS element
631 return (expectedOSName != null || expectedOSFamily != null || expectedOSArch != null || expectedOSVersion != null);
632 }
633
634 public boolean isActiveByJDK() {
635 final Element activation = getFirstChildElement(profileElement, ACTIVATION_ELEMENT);
636 if (activation == null) {
637 return false;
638 }
639 final String expectedJDKRange = getFirstChildText(activation, JDK);
640 if (expectedJDKRange == null) {
641 return false;
642 }
643 final boolean negate = expectedJDKRange.trim().startsWith("!");
644 final String nonNegatedRange = negate ? expectedJDKRange.substring(1).trim() : expectedJDKRange.trim();
645 final boolean javaVersionInRange = MavenVersionRangeParser.currentJavaVersionInRange(nonNegatedRange);
646 return javaVersionInRange ^ negate;
647 }
648
649 public boolean isActiveByFile() {
650 final Element activation = getFirstChildElement(profileElement, ACTIVATION_ELEMENT);
651 if (activation == null) {
652 return false;
653 }
654 final Element fileActivation = getFirstChildElement(activation, FILE);
655 if (fileActivation == null) {
656 return false;
657 }
658 final String expectedMissing = getFirstChildText(fileActivation, MISSING);
659 if (expectedMissing != null && new File(expectedMissing.trim()).exists()) {
660 // the file was specified and expected to be missing, but it exists
661 return false;
662 }
663 final String expectedExists = getFirstChildText(fileActivation, EXISTS);
664 if (expectedExists != null && !(new File(expectedExists.trim()).exists())) {
665 // the file was specified and expected to be existing, but it doesn't
666 return false;
667 }
668 // reaching here implies that either no file match rules were specified or
669 // all of the file rules that were specified were matched. So we just check to see
670 // if any rules were specified at all, in which case, we consider the profile to be activated
671 // by the file element
672 return (expectedMissing != null || expectedExists != null);
673 }
674
675 public boolean isActivatedByProperty() {
676 Element activation = getFirstChildElement(profileElement, ACTIVATION_ELEMENT);
677 Element propertyActivation = getFirstChildElement(activation, PROPERTY);
678 String propertyName = getFirstChildText(propertyActivation, NAME);
679 if (propertyName == null || "".equals(propertyName)) {
680 return false;
681 }
682 boolean negate = propertyName.charAt(0) == '!';
683 if (negate) {
684 propertyName = propertyName.substring(1);
685 }
686 if ("".equals(propertyName)) {
687 return false;
688 }
689 String propertyValue = getFirstChildText(propertyActivation, VALUE);
690
691 final boolean matched;
692 if (propertyValue == null || "".equals(propertyValue)) {
693 matched = PomReader.this.properties.containsKey(propertyName);
694 } else {
695 matched = propertyValue.equals(PomReader.this.properties.get(propertyName));
696 }
697 return matched ^ negate;
698 }
699
700 public List<PomDependencyData> getDependencies() {
701 return PomReader.this.getDependencies(profileElement);
702 }
703
704 public List<PomDependencyMgt> getDependencyMgt() {
705 return PomReader.this.getDependencyMgt(profileElement);
706 }
707
708 public List<PomPluginElement> getPlugins() {
709 return PomReader.this.getPlugins(profileElement);
710 }
711
712 public Map<String, String> getProfileProperties() {
713 return PomReader.getProperties(profileElement);
714 }
460715 }
461716
462717 /**
463718 * @return the content of the properties tag into the pom.
464719 */
465 public Map/* <String,String> */getPomProperties() {
466 Map pomProperties = new HashMap();
467 Element propsEl = getFirstChildElement(projectElement, PROPERTIES);
468 if (propsEl != null) {
469 propsEl.normalize();
470 }
471 for (Iterator it = getAllChilds(propsEl).iterator(); it.hasNext();) {
472 Element prop = (Element) it.next();
473 pomProperties.put(prop.getNodeName(), getTextContent(prop));
474 }
475 return pomProperties;
720 public Map<String, String> getPomProperties() {
721 return new HashMap<>(getProperties(projectElement));
476722 }
477723
478724 private String replaceProps(String val) {
484730 }
485731
486732 private static String getTextContent(Element element) {
487 StringBuffer result = new StringBuffer();
733 StringBuilder result = new StringBuilder();
488734
489735 NodeList childNodes = element.getChildNodes();
490736 for (int i = 0; i < childNodes.getLength(); i++) {
526772 return null;
527773 }
528774
529 private static List/* <Element> */getAllChilds(Element parent) {
530 List r = new LinkedList();
775 private static List<Element> getAllChilds(Element parent) {
776 List<Element> r = new LinkedList<>();
531777 if (parent != null) {
532778 NodeList childs = parent.getChildNodes();
533779 for (int i = 0; i < childs.getLength(); i++) {
534780 Node node = childs.item(i);
535781 if (node instanceof Element) {
536 r.add(node);
782 r.add((Element) node);
537783 }
538784 }
539785 }
568814 }
569815
570816 int bytesToSkip = 0;
571 LineNumberReader reader = new LineNumberReader(new InputStreamReader(this.in, "UTF-8"),
817 LineNumberReader reader = new LineNumberReader(new InputStreamReader(this.in, StandardCharsets.UTF_8),
572818 100);
573819 String firstLine = reader.readLine();
574820 if (firstLine != null) {
589835 }
590836 }
591837
838 @Override
592839 public int read() throws IOException {
593840 if (count < prefix.length) {
594841 return prefix[count++];
595842 }
596843
597 int result = super.read();
598 return result;
599 }
600
844 return super.read();
845 }
846
847 @Override
601848 public int read(byte[] b, int off, int len) throws IOException {
602849 if (b == null) {
603850 throw new NullPointerException();
604 } else if ((off < 0) || (off > b.length) || (len < 0) || ((off + len) > b.length)
605 || ((off + len) < 0)) {
851 } else if (off < 0 || off > b.length || len < 0 || (off + len) > b.length
852 || (off + len) < 0) {
606853 throw new IndexOutOfBoundsException();
607854 } else if (len == 0) {
608855 return 0;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.io.File;
2020 import java.util.ArrayList;
21 import java.util.HashMap;
21 import java.util.LinkedHashMap;
2222 import java.util.List;
2323 import java.util.Map;
2424
3636
3737 private String artifactPackaging;
3838
39 private List/* <ExtraDependency> */extraDependencies = new ArrayList();
39 private List<ExtraDependency> extraDependencies = new ArrayList<>();
4040
4141 private String description;
4242
9090 return this;
9191 }
9292
93 public List/* <ExtraDependency> */getExtraDependencies() {
93 public List<ExtraDependency> getExtraDependencies() {
9494 return extraDependencies;
9595 }
9696
97 public PomWriterOptions setExtraDependencies(List/* <ExtraDependency> */extraDependencies) {
97 public PomWriterOptions setExtraDependencies(List<ExtraDependency> extraDependencies) {
9898 this.extraDependencies = extraDependencies;
9999 return this;
100100 }
127127 }
128128
129129 public static class ConfigurationScopeMapping {
130 private Map/* <String,String> */scopes;
131
132 public ConfigurationScopeMapping(Map/* <String,String> */scopesMapping) {
133 this.scopes = new HashMap(scopesMapping);
130 private Map<String, String> scopes;
131
132 public ConfigurationScopeMapping(Map<String, String> scopesMapping) {
133 // preserve the order
134 this.scopes = new LinkedHashMap<>(scopesMapping);
134135 }
135136
136137 /**
137138 * Returns the scope mapped to the given configuration array.
138 *
139 *
139140 * @param confs
140141 * the configurations for which the scope should be returned
141142 * @return the scope to which the conf is mapped
142143 */
143144 public String getScope(String[] confs) {
144 for (int i = 0; i < confs.length; i++) {
145 if (scopes.containsKey(confs[i])) {
146 return (String) scopes.get(confs[i]);
145 for (String conf : confs) {
146 if (scopes.containsKey(conf)) {
147 return scopes.get(conf);
147148 }
148149 }
149150
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
1818 <!ENTITY nbsp "&#160;">
1919 <!ENTITY iexcl "&#161;">
66 SKIP_LINE * "License"); you may not use this file except in compliance
77 SKIP_LINE * with the License. You may obtain a copy of the License at
88 SKIP_LINE *
9 SKIP_LINE * http://www.apache.org/licenses/LICENSE-2.0
9 SKIP_LINE * https://www.apache.org/licenses/LICENSE-2.0
1010 SKIP_LINE *
1111 SKIP_LINE * Unless required by applicable law or agreed to in writing,
1212 SKIP_LINE * software distributed under the License is distributed on an
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.Map;
2222
2323 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
24 import org.apache.ivy.core.module.id.ModuleRevisionId;
2425 import org.apache.ivy.plugins.namespace.Namespace;
2526 import org.apache.ivy.plugins.parser.ParserSettings;
2627
3839 /**
3940 * Map from ModuleId of dependencies to new revision (as String)
4041 */
41 private Map resolvedRevisions = Collections.EMPTY_MAP;
42 private Map<ModuleRevisionId, String> resolvedRevisions = Collections.emptyMap();
4243
4344 /**
4445 * Map from ModuleId of dependencies to new branch (as String)
4546 */
46 private Map resolvedBranches = Collections.EMPTY_MAP;
47 private Map<ModuleRevisionId, String> resolvedBranches = Collections.emptyMap();
4748
4849 /**
4950 * the new status, <code>null</code> to keep the old one
109110 return this;
110111 }
111112
112 public Map getResolvedRevisions() {
113 public Map<ModuleRevisionId, String> getResolvedRevisions() {
113114 return resolvedRevisions;
114115 }
115116
116 public UpdateOptions setResolvedRevisions(Map resolvedRevisions) {
117 public UpdateOptions setResolvedRevisions(Map<ModuleRevisionId, String> resolvedRevisions) {
117118 this.resolvedRevisions = resolvedRevisions;
118119 return this;
119120 }
210211 return this;
211212 }
212213
213 public Map getResolvedBranches() {
214 public Map<ModuleRevisionId, String> getResolvedBranches() {
214215 return resolvedBranches;
215216 }
216217
217 public UpdateOptions setResolvedBranches(Map resolvedBranches) {
218 public UpdateOptions setResolvedBranches(Map<ModuleRevisionId, String> resolvedBranches) {
218219 this.resolvedBranches = resolvedBranches;
219220 return this;
220221 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
8181 import org.xml.sax.Attributes;
8282 import org.xml.sax.SAXException;
8383
84 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.getVisibility;
85 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
86 import static org.apache.ivy.util.StringUtils.splitToArray;
87
8488 /**
8589 * Parses an xml ivy file and output a ModuleDescriptor. For dependency and performance reasons, it
8690 * uses only the SAX API, which makes the parsing code harder to understand.
8791 */
8892 public class XmlModuleDescriptorParser extends AbstractModuleDescriptorParser {
89 static final String[] DEPENDENCY_REGULAR_ATTRIBUTES = new String[] {"org", "name", "branch",
90 "branchConstraint", "rev", "revConstraint", "force", "transitive", "changing", "conf"};
93 static final List<String> DEPENDENCY_REGULAR_ATTRIBUTES = Arrays.asList("org", "name", "branch",
94 "branchConstraint", "rev", "revConstraint", "force", "transitive", "changing", "conf");
9195
9296 private static final XmlModuleDescriptorParser INSTANCE = new XmlModuleDescriptorParser();
9397
99103 }
100104
101105 /**
102 * @param settings
106 * @param ivySettings ParserSettings
103107 * @param xmlURL
104108 * the url pointing to the file to parse
105109 * @param res
106110 * the real resource to parse, used for log only
107 * @param validate
108 * @return
109 * @throws ParseException
110 * @throws IOException
111 * @param validate boolean
112 * @return ModuleDescriptor
113 * @throws ParseException if something goes wrong
114 * @throws IOException if something goes wrong
111115 */
112116 public ModuleDescriptor parseDescriptor(ParserSettings ivySettings, URL xmlURL, Resource res,
113117 boolean validate) throws ParseException, IOException {
121125
122126 /** Used for test purpose */
123127 ModuleDescriptor parseDescriptor(ParserSettings ivySettings, InputStream descriptor,
124 Resource res, boolean validate) throws ParseException, IOException {
128 Resource res, boolean validate) throws ParseException {
125129 Parser parser = newParser(ivySettings);
126130 parser.setValidate(validate);
127131 parser.setResource(res);
135139 * <p>
136140 * Override this method if you want to use a custom Parser.
137141 * </p>
138 *
142 *
139143 * @param ivySettings
140144 * the settings to use during parsing
141145 * @return the Parser instance used for parsing Ivy files
166170 .setPubdate(md.getResolvedPublicationDate()).setUpdateBranch(false)
167171 .setNamespace(ns));
168172 } catch (SAXException e) {
169 ParseException ex = new ParseException("exception occurred while parsing " + res, 0);
170 ex.initCause(e);
171 throw ex;
173 ParseException pe = new ParseException("exception occurred while parsing " + res, 0);
174 pe.initCause(e);
175 throw pe;
172176 } finally {
173177 if (is != null) {
174178 is.close();
208212 }
209213 }
210214
211 protected static final List ALLOWED_VERSIONS = Arrays.asList(new String[] {"1.0", "1.1",
212 "1.2", "1.3", "1.4", "2.0", "2.1", "2.2", "2.3", "2.4"});
215 protected static final List<String> ALLOWED_VERSIONS = Arrays.asList("1.0",
216 "1.1", "1.2", "1.3", "1.4", "2.0", "2.1", "2.2", "2.3", "2.4");
213217
214218 /* how and what do we have to parse */
215219 private ParserSettings settings;
235239
236240 private boolean artifactsDeclared = false;
237241
238 private StringBuffer buffer;
242 private StringBuilder buffer;
239243
240244 private String descriptorVersion;
241245
242246 private String[] publicationsDefaultConf;
243247
244 private Stack<ExtraInfoHolder> extraInfoStack = new Stack<ExtraInfoHolder>();
248 private Stack<ExtraInfoHolder> extraInfoStack = new Stack<>();
245249
246250 public Parser(ModuleDescriptorParser parser, ParserSettings ivySettings) {
247251 super(parser);
260264 this.validate = validate;
261265 }
262266
263 public void parse() throws ParseException, IOException {
267 public void parse() throws ParseException {
264268 try {
265269 URL schemaURL = validate ? getSchemaURL() : null;
266270 if (descriptorURL != null) {
274278 DefaultArtifact.newIvyArtifact(getMd().getResolvedModuleRevisionId(), getMd()
275279 .getPublicationDate()));
276280 if (!artifactsDeclared) {
277 String[] confs = getMd().getConfigurationsNames();
278 for (int i = 0; i < confs.length; i++) {
279 getMd().addArtifact(
280 confs[i],
281 new MDArtifact(getMd(), getMd().getModuleRevisionId().getName(), "jar",
282 "jar"));
281 for (String config : getMd().getConfigurationsNames()) {
282 getMd().addArtifact(config, new MDArtifact(getMd(),
283 getMd().getModuleRevisionId().getName(), "jar", "jar"));
283284 }
284285 }
285286 getMd().check();
286287 } catch (ParserConfigurationException ex) {
287 IllegalStateException ise = new IllegalStateException(ex.getMessage() + " in "
288 + descriptorURL);
289 ise.initCause(ex);
290 throw ise;
288 throw new IllegalStateException(ex.getMessage() + " in "
289 + descriptorURL, ex);
291290 } catch (Exception ex) {
292291 checkErrors();
293292 ParseException pe = new ParseException(ex.getMessage() + " in " + descriptorURL, 0);
296295 }
297296 }
298297
298 @Override
299299 public void startElement(String uri, String localName, String qName, Attributes attributes)
300300 throws SAXException {
301301 try {
310310 getBuffer().append("\"");
311311 }
312312 getBuffer().append(">");
313 return;
314313 } else if ("ivy-module".equals(qName)) {
315314 ivyModuleStarted(attributes);
316315 } else if ("info".equals(qName)) {
324323 } else if (state == State.INFO && "description".equals(qName)) {
325324 getMd().setHomePage(settings.substitute(attributes.getValue("homepage")));
326325 state = State.DESCRIPTION;
327 buffer = new StringBuffer();
326 buffer = new StringBuilder();
328327 } else if (state == State.INFO && "ivyauthor".equals(qName)) {
329328 // nothing to do, we don't store this
330329 } else if (state == State.INFO && "repository".equals(qName)) {
331330 // nothing to do, we don't store this
332331 } else if (state == State.EXTRA_INFO || state == State.INFO
333332 && isOtherNamespace(qName)) {
334 buffer = new StringBuffer();
333 buffer = new StringBuilder();
335334 state = State.EXTRA_INFO;
336335 ExtraInfoHolder extraInfo = new ExtraInfoHolder();
337336 extraInfo.setName(qName);
371370 } else if ("mapped".equals(qName)) {
372371 dd.addDependencyConfiguration(conf,
373372 settings.substitute(attributes.getValue("name")));
374 } else if (("conflict".equals(qName) && state == State.DEPS)
373 } else if ("conflict".equals(qName) && state == State.DEPS
375374 || "manager".equals(qName) && state == State.CONFLICT) {
376375 managerStarted(attributes, state == State.CONFLICT ? "name" : "manager");
377376 } else if ("override".equals(qName) && state == State.DEPS) {
385384 if (ex instanceof SAXException) {
386385 throw (SAXException) ex;
387386 }
388 SAXException sax = new SAXException("Problem occurred while parsing ivy file: "
387 throw new SAXException("Problem occurred while parsing ivy file: "
389388 + ex.getMessage(), ex);
390 sax.initCause(ex);
391 throw sax;
392389 }
393390 }
394391
395392 /**
396393 * Default parent location to check (for dev ONLY)
397 *
394 *
398395 * @return a relative path to a parent module descriptor
399396 */
400397 protected String getDefaultParentLocation() {
409406 * <li>cache to find a resolved parent descriptor</li>
410407 * <li>ask repositories to retrieve the parent module descriptor</li>
411408 * </ul>
412 *
413 * @param attributes
414 * @throws ParseException
409 *
410 * @param attributes Attributes
411 * @throws ParseException if something goes wrong
415412 */
416413 protected void extendsStarted(Attributes attributes) throws ParseException {
417414 String parentOrganisation = settings.substitute(attributes.getValue("organisation"));
418415 String parentModule = settings.substitute(attributes.getValue("module"));
419 String parentRevision = attributes.getValue("revision") != null ? settings
420 .substitute(attributes.getValue("revision")) : Ivy.getWorkingRevision();
421 String location = attributes.getValue("location") != null ? settings
422 .substitute(attributes.getValue("location")) : getDefaultParentLocation();
423 ModuleDescriptor parent = null;
424
425 String extendType = attributes.getValue("extendType") != null ? settings
426 .substitute(attributes.getValue("extendType").toLowerCase(Locale.US)) : "all";
427
428 List/* <String> */extendTypes = Arrays.asList(extendType.split(","));
416 String parentRevision = (attributes.getValue("revision") == null) ? Ivy.getWorkingRevision()
417 : settings.substitute(attributes.getValue("revision"));
418 String location = (attributes.getValue("location") == null) ? getDefaultParentLocation()
419 : settings.substitute(attributes.getValue("location"));
420 String extendType = (attributes.getValue("extendType") == null) ? "all"
421 : settings.substitute(attributes.getValue("extendType").toLowerCase(Locale.US));
422
423 List<String> extendTypes = Arrays.asList(extendType.split(","));
429424 ModuleId parentMid = new ModuleId(parentOrganisation, parentModule);
430425 ModuleRevisionId parentMrid = new ModuleRevisionId(parentMid, parentRevision);
431426
432427 // check on filesystem based on location attribute (for dev ONLY)
428 ModuleDescriptor parent = null;
433429 boolean local = false;
434430 try {
435431 parent = parseParentModuleOnFilesystem(location);
471467 }
472468
473469 DefaultExtendsDescriptor ed = new DefaultExtendsDescriptor(parent, location,
474 (String[]) extendTypes.toArray(new String[extendTypes.size()]), local);
470 extendTypes.toArray(new String[extendTypes.size()]), local);
475471 getMd().addInheritedDescriptor(ed);
476472
477473 mergeWithOtherModuleDescriptor(extendTypes, parent);
480476 /**
481477 * Merge current module with a given module descriptor and specify what should be inherited
482478 * through extendTypes argument
483 *
479 *
484480 * @param extendTypes
485481 * specify what should be inherited
486482 * @param parent
487483 * a given parent module descriptor
488484 */
489 protected void mergeWithOtherModuleDescriptor(List/* <String> */extendTypes,
490 ModuleDescriptor parent) throws ParseException {
485 protected void mergeWithOtherModuleDescriptor(List<String> extendTypes,
486 ModuleDescriptor parent) {
491487
492488 if (extendTypes.contains("all")) {
493489 mergeAll(parent);
507503 if (extendTypes.contains("description")) {
508504 mergeDescription(parent.getDescription());
509505 }
506
510507 if (extendTypes.contains("licenses")) {
511508 mergeLicenses(parent.getLicenses());
512509 }
510
513511 if (extendTypes.contains("excludes")) {
514512 mergeExcludes(parent.getAllExcludeRules());
515513 }
519517
520518 /**
521519 * Merge everything from a given parent
522 *
520 *
523521 * @param parent
524 * a given parent module desciptor
522 * a given parent module descriptor
525523 */
526524 protected void mergeAll(ModuleDescriptor parent) {
527525 mergeInfo(parent);
533531 }
534532
535533 /**
536 * Explain how to inherit metadatas related to info element
537 *
534 * Explain how to inherit metadata related to info element
535 *
538536 * @param parent
539 * a given parent module decriptor
537 * a given parent module descriptor
540538 */
541539 protected void mergeInfo(ModuleDescriptor parent) {
542540 ModuleRevisionId parentMrid = parent.getModuleRevisionId();
576574 return override == null ? inherited : override;
577575 }
578576
579 private static Map mergeValues(Map inherited, Map overrides) {
580 LinkedHashMap dup = new LinkedHashMap(inherited.size() + overrides.size());
577 private static Map<String, String> mergeValues(Map<String, String> inherited,
578 Map<String, String> overrides) {
579 Map<String, String> dup = new LinkedHashMap<>(inherited.size()
580 + overrides.size());
581581 dup.putAll(inherited);
582582 dup.putAll(overrides);
583583 return dup;
585585
586586 /**
587587 * Describes how to merge configurations elements
588 *
589 * @param sourceMrid
590 * the source module revision id
591 * @param configurations
592 * array of configurations to be inherited
588 *
589 * @param parent
590 * the module descriptor
593591 */
594592 protected void mergeConfigurations(ModuleDescriptor parent) {
595593 ModuleRevisionId sourceMrid = parent.getModuleRevisionId();
596 Configuration[] configurations = parent.getConfigurations();
597 for (int i = 0; i < configurations.length; i++) {
598 Configuration configuration = configurations[i];
594 for (Configuration configuration : parent.getConfigurations()) {
599595 Message.debug("Merging configuration with: " + configuration.getName());
600596 // copy configuration from parent descriptor
601597 getMd().addConfiguration(new Configuration(configuration, sourceMrid));
610606
611607 /**
612608 * Describes how dependencies should be inherited
613 *
609 *
614610 * @param dependencies
615611 * array of dependencies to inherit
616612 */
617613 protected void mergeDependencies(DependencyDescriptor[] dependencies) {
618614 DefaultModuleDescriptor md = getMd();
619 for (int i = 0; i < dependencies.length; i++) {
620 DependencyDescriptor dependencyDescriptor = dependencies[i];
615 for (DependencyDescriptor dependencyDescriptor : dependencies) {
621616 Message.debug("Merging dependency with: "
622617 + dependencyDescriptor.getDependencyRevisionId().toString());
623618 md.addDependency(dependencyDescriptor);
626621
627622 /**
628623 * Describes how to merge description
629 *
624 *
630625 * @param description
631626 * description going to be inherited
632627 */
633628 protected void mergeDescription(String description) {
634629 String current = getMd().getDescription();
635 if (current == null || current.trim().length() == 0) {
630 if (isNullOrEmpty(current)) {
636631 getMd().setDescription(description);
637632 }
638633 }
639634
640635 /**
641636 * Describes how to merge licenses
642 *
637 *
643638 * @param licenses
644639 * licenses going to be inherited
645640 */
646641 public void mergeLicenses(License[] licenses) {
647 for (int i = 0; i < licenses.length; i++) {
648 getMd().addLicense(licenses[i]);
642 for (License license : licenses) {
643 getMd().addLicense(license);
649644 }
650645 }
651646
652647 /**
653648 * Describes how to merge exclude rules
654 *
649 *
655650 * @param excludeRules
656651 * exclude rules going to be inherited
657652 */
658653 public void mergeExcludes(ExcludeRule[] excludeRules) {
659 for (int i = 0; i < excludeRules.length; i++) {
660 getMd().addExcludeRule(excludeRules[i]);
654 for (ExcludeRule excludeRule : excludeRules) {
655 getMd().addExcludeRule(excludeRule);
661656 }
662657 }
663658
664659 /**
665660 * Returns the parent module using the location attribute (for dev purpose).
666 *
661 *
667662 * @param location
668663 * a given location
669 * @throws IOException
670 * @throws ParseException
664 * @throws IOException if something goes wrong
665 * @throws ParseException if something goes wrong
671666 */
672667 private ModuleDescriptor parseParentModuleOnFilesystem(String location) throws IOException,
673668 ParseException {
695690 FileResource res = new FileResource(null, file);
696691 ModuleDescriptorParser parser = ModuleDescriptorParserRegistry.getInstance().getParser(
697692 res);
698 return parser.parseDescriptor(getSettings(), file.toURL(), res, isValidate());
693 return parser.parseDescriptor(getSettings(), file.toURI().toURL(), res, isValidate());
699694 }
700695
701696 /**
702697 * Describe how to parse a {@link ModuleDescriptor} by asking repositories
703 *
698 *
704699 * @param parentMrid
705700 * a given {@link ModuleRevisionId} to find
706701 * @return a {@link ModuleDescriptor} if found. Return null if no {@link ModuleDescriptor}
707702 * was found
708 * @throws ParseException
703 * @throws ParseException if something goes wrong
709704 */
710705 protected ModuleDescriptor parseOtherIvyFile(ModuleRevisionId parentMrid)
711706 throws ParseException {
740735 }
741736
742737 protected void setPublicationsDefaultConf(String defaultConf) {
743 this.publicationsDefaultConf = defaultConf == null ? null : defaultConf.split(",");
738 this.publicationsDefaultConf = (defaultConf == null) ? null : splitToArray(defaultConf);
744739 }
745740
746741 protected boolean isOtherNamespace(String qName) {
747 return qName.indexOf(':') != -1;
742 return qName.contains(":");
748743 }
749744
750745 protected void managerStarted(Attributes attributes, String managerAtt) {
751746 String org = settings.substitute(attributes.getValue("org"));
752 org = org == null ? PatternMatcher.ANY_EXPRESSION : org;
747 if (org == null) {
748 org = PatternMatcher.ANY_EXPRESSION;
749 }
753750 String mod = settings.substitute(attributes.getValue("module"));
754 mod = mod == null ? PatternMatcher.ANY_EXPRESSION : mod;
751 if (mod == null) {
752 mod = PatternMatcher.ANY_EXPRESSION;
753 }
755754 ConflictManager cm;
756755 String name = settings.substitute(attributes.getValue(managerAtt));
757756 String rev = settings.substitute(attributes.getValue("rev"));
758757 if (rev != null) {
759 String[] revs = rev.split(",");
760 for (int i = 0; i < revs.length; i++) {
761 revs[i] = revs[i].trim();
762 }
763 cm = new FixedConflictManager(revs);
758 cm = new FixedConflictManager(splitToArray(rev));
764759 } else if (name != null) {
765760 cm = settings.getConflictManager(name);
766761 if (cm == null) {
772767 return;
773768 }
774769 String matcherName = settings.substitute(attributes.getValue("matcher"));
775 PatternMatcher matcher = matcherName == null ? defaultMatcher : settings
776 .getMatcher(matcherName);
770 PatternMatcher matcher = (matcherName == null) ? defaultMatcher
771 : settings.getMatcher(matcherName);
777772 if (matcher == null) {
778773 addError("unknown matcher: " + matcherName);
779774 return;
783778
784779 protected void mediationOverrideStarted(Attributes attributes) {
785780 String org = settings.substitute(attributes.getValue("org"));
786 org = org == null ? PatternMatcher.ANY_EXPRESSION : org;
781 if (org == null) {
782 org = PatternMatcher.ANY_EXPRESSION;
783 }
787784 String mod = settings.substitute(attributes.getValue("module"));
788 mod = mod == null ? PatternMatcher.ANY_EXPRESSION : mod;
785 if (mod == null) {
786 mod = PatternMatcher.ANY_EXPRESSION;
787 }
789788 String rev = settings.substitute(attributes.getValue("rev"));
790789 String branch = settings.substitute(attributes.getValue("branch"));
791790 String matcherName = settings.substitute(attributes.getValue("matcher"));
792 PatternMatcher matcher = matcherName == null ? defaultMatcher : settings
793 .getMatcher(matcherName);
791 PatternMatcher matcher = (matcherName == null) ? defaultMatcher
792 : settings.getMatcher(matcherName);
794793 if (matcher == null) {
795794 addError("unknown matcher: " + matcherName);
796795 return;
813812 // the specified file.
814813 Parser parser = new Parser(getModuleDescriptorParser(), settings);
815814 parser.setInput(url);
816 parser.setMd(new DefaultModuleDescriptor(getModuleDescriptorParser(), new URLResource(
817 url)));
815 parser.setMd(new DefaultModuleDescriptor(getModuleDescriptorParser(),
816 new URLResource(url)));
818817 XMLHelper.parse(url, null, parser);
819818
820819 // add the configurations from this temporary parser to this module descriptor
821 Configuration[] configs = parser.getModuleDescriptor().getConfigurations();
822 for (int i = 0; i < configs.length; i++) {
823 getMd().addConfiguration(configs[i]);
820 for (Configuration config : parser.getModuleDescriptor().getConfigurations()) {
821 getMd().addConfiguration(config);
824822 }
825823 if (parser.getDefaultConfMapping() != null) {
826824 Message.debug("setting default conf mapping from imported configurations file: "
845843 String visibility = settings.substitute(attributes.getValue("visibility"));
846844 String ext = settings.substitute(attributes.getValue("extends"));
847845 String transitiveValue = attributes.getValue("transitive");
848 boolean transitive = (transitiveValue == null) ? true : Boolean.valueOf(
849 attributes.getValue("transitive")).booleanValue();
846 boolean transitive = (transitiveValue == null)
847 || Boolean.valueOf(attributes.getValue("transitive"));
850848 String deprecated = attributes.getValue("deprecated");
851849 Configuration configuration = new Configuration(conf,
852 Configuration.Visibility.getVisibility(visibility == null ? "public"
853 : visibility), settings.substitute(attributes
854 .getValue("description")), ext == null ? null : ext.split(","),
855 transitive, deprecated);
850 getVisibility((visibility == null) ? "public" : visibility),
851 settings.substitute(attributes.getValue("description")),
852 (ext == null) ? null : ext.split(","), transitive, deprecated);
856853 ExtendableItemHelper.fillExtraAttributes(settings, configuration, attributes,
857 new String[] {"name", "visibility", "extends", "transitive", "description",
858 "deprecated"});
854 Arrays.asList("name", "visibility", "extends", "transitive", "description",
855 "deprecated"));
859856 getMd().addConfiguration(configuration);
860857 break;
861858 case State.PUB:
862859 if ("*".equals(conf)) {
863 String[] confs = getMd().getConfigurationsNames();
864 for (int i = 0; i < confs.length; i++) {
865 artifact.addConfiguration(confs[i]);
866 getMd().addArtifact(confs[i], artifact);
860 for (String config : getMd().getConfigurationsNames()) {
861 artifact.addConfiguration(config);
862 getMd().addArtifact(config, artifact);
867863 }
868864 } else {
869865 artifact.addConfiguration(conf);
874870 this.conf = conf;
875871 String mappeds = settings.substitute(attributes.getValue("mapped"));
876872 if (mappeds != null) {
877 String[] mapped = mappeds.split(",");
878 for (int i = 0; i < mapped.length; i++) {
879 dd.addDependencyConfiguration(conf, mapped[i].trim());
873 for (String mapped : splitToArray(mappeds)) {
874 dd.addDependencyConfiguration(conf, mapped);
880875 }
881876 }
882877 break;
899894 if (org == null) {
900895 org = getMd().getModuleRevisionId().getOrganisation();
901896 }
902 boolean force = Boolean.valueOf(settings.substitute(attributes.getValue("force")))
903 .booleanValue();
904 boolean changing = Boolean
905 .valueOf(settings.substitute(attributes.getValue("changing"))).booleanValue();
897 boolean force = Boolean.valueOf(settings.substitute(attributes.getValue("force")));
898 boolean changing = Boolean.valueOf(settings.substitute(attributes.getValue("changing")));
906899
907900 String transitiveValue = settings.substitute(attributes.getValue("transitive"));
908 boolean transitive = (transitiveValue == null) ? true : Boolean.valueOf(
909 attributes.getValue("transitive")).booleanValue();
901 boolean transitive = (transitiveValue == null)
902 || Boolean.valueOf(attributes.getValue("transitive"));
910903
911904 String name = settings.substitute(attributes.getValue("name"));
912905 String branch = settings.substitute(attributes.getValue("branch"));
913906 String branchConstraint = settings.substitute(attributes.getValue("branchConstraint"));
914907
915 // if (branchConstraint == null) {
916 // // there was no branch constraint before, so we should
917 // // set the branchConstraint to the current default branch
918 // branchConstraint = settings.getDefaultBranch(ModuleId.newInstance(org, name));
919 // }
908 /* if (branchConstraint == null) {
909 * // there was no branch constraint before, so we should
910 * // set the branchConstraint to the current default branch
911 * branchConstraint = settings.getDefaultBranch(ModuleId.newInstance(org, name));
912 * }
913 */
920914
921915 String rev = settings.substitute(attributes.getValue("rev"));
922916 String revConstraint = settings.substitute(attributes.getValue("revConstraint"));
923917
924 Map extraAttributes = ExtendableItemHelper.getExtraAttributes(settings, attributes,
925 DEPENDENCY_REGULAR_ATTRIBUTES);
918 Map<String, String> extraAttributes = ExtendableItemHelper.getExtraAttributes(settings,
919 attributes, DEPENDENCY_REGULAR_ATTRIBUTES);
926920
927921 ModuleRevisionId revId = ModuleRevisionId.newInstance(org, name, branch, rev,
928922 extraAttributes);
929923 ModuleRevisionId dynamicId = null;
930 if ((revConstraint == null) && (branchConstraint == null)) {
924 if (revConstraint == null && branchConstraint == null) {
931925 // no dynamic constraints defined, so dynamicId equals revId
932926 dynamicId = ModuleRevisionId.newInstance(org, name, branch, rev, extraAttributes,
933927 false);
958952 if (state == State.PUB) {
959953 // this is a published artifact
960954 String artName = settings.substitute(attributes.getValue("name"));
961 artName = artName == null ? getMd().getModuleRevisionId().getName() : artName;
955 if (artName == null) {
956 artName = getMd().getModuleRevisionId().getName();
957 }
962958 String type = settings.substitute(attributes.getValue("type"));
963 type = type == null ? "jar" : type;
959 if (type == null) {
960 type = "jar";
961 }
964962 String ext = settings.substitute(attributes.getValue("ext"));
965 ext = ext != null ? ext : type;
963 if (ext == null) {
964 ext = type;
965 }
966966 String url = settings.substitute(attributes.getValue("url"));
967967 artifact = new MDArtifact(getMd(), artName, type, ext, url == null ? null
968968 : new URL(url), ExtendableItemHelper.getExtraAttributes(settings,
969 attributes, new String[] {"ext", "type", "name", "conf"}));
969 attributes, Arrays.asList("ext", "type", "name", "conf")));
970970 String confs = settings.substitute(attributes.getValue("conf"));
971971 // only add confs if they are specified. if they aren't, endElement will
972972 // handle this
973973 // only if there are no conf defined in sub elements
974974 if (confs != null && confs.length() > 0) {
975 String[] conf;
976 if ("*".equals(confs)) {
977 conf = getMd().getConfigurationsNames();
978 } else {
979 conf = confs.split(",");
980 }
981 for (int i = 0; i < conf.length; i++) {
982 artifact.addConfiguration(conf[i].trim());
983 getMd().addArtifact(conf[i].trim(), artifact);
975 String[] configs = "*".equals(confs) ? getMd().getConfigurationsNames()
976 : splitToArray(confs);
977 for (String config : configs) {
978 artifact.addConfiguration(config);
979 getMd().addArtifact(config, artifact);
984980 }
985981 }
986982 } else if (state == State.DEP) {
10041000 String confMappingOverride = settings.substitute(attributes
10051001 .getValue("confmappingoverride"));
10061002 if (confMappingOverride != null) {
1007 getMd().setMappingOverride(Boolean.valueOf(confMappingOverride).booleanValue());
1003 getMd().setMappingOverride(Boolean.valueOf(confMappingOverride));
10081004 }
10091005 checkConfigurations();
10101006 }
10141010 setDefaultConfMapping(settings.substitute(attributes.getValue("defaultconfmapping")));
10151011 setDefaultConf(settings.substitute(attributes.getValue("defaultconf")));
10161012 getMd().setMappingOverride(
1017 Boolean.valueOf(settings.substitute(attributes.getValue("confmappingoverride")))
1018 .booleanValue());
1013 Boolean.valueOf(settings.substitute(attributes.getValue("confmappingoverride"))));
10191014 }
10201015
10211016 protected void infoStarted(Attributes attributes) {
10301025 module,
10311026 branch,
10321027 revision,
1033 ExtendableItemHelper.getExtraAttributes(settings, attributes, new String[] {
1028 ExtendableItemHelper.getExtraAttributes(settings, attributes, Arrays.asList(
10341029 "organisation", "module", "revision", "status", "publication",
1035 "branch", "namespace", "default", "resolver"})));
1030 "branch", "namespace", "default", "resolver"))));
10361031
10371032 String namespace = settings.substitute(attributes.getValue("namespace"));
10381033 if (namespace != null) {
10491044 getMd().setStatus(
10501045 status == null ? settings.getStatusManager().getDefaultStatus() : status);
10511046 getMd().setDefault(
1052 Boolean.valueOf(settings.substitute(attributes.getValue("default"))).booleanValue());
1047 Boolean.valueOf(settings.substitute(attributes.getValue("default"))));
10531048 String pubDate = settings.substitute(attributes.getValue("publication"));
10541049 if (pubDate != null && pubDate.length() > 0) {
10551050 try {
11201115 type = "artifact".equals(tag) ? "jar" : PatternMatcher.ANY_EXPRESSION;
11211116 }
11221117 String ext = settings.substitute(attributes.getValue("ext"));
1123 ext = ext != null ? ext : type;
1124 if (state == State.DEP_ARTIFACT) {
1125 String url = settings.substitute(attributes.getValue("url"));
1126 Map extraAtt = ExtendableItemHelper.getExtraAttributes(settings, attributes,
1127 new String[] {"name", "type", "ext", "url", "conf"});
1128 confAware = new DefaultDependencyArtifactDescriptor(dd, name, type, ext,
1129 url == null ? null : new URL(url), extraAtt);
1130 } else if (state == State.ARTIFACT_INCLUDE) {
1131 PatternMatcher matcher = getPatternMatcher(attributes.getValue("matcher"));
1132 String org = settings.substitute(attributes.getValue("org"));
1133 org = org == null ? PatternMatcher.ANY_EXPRESSION : org;
1134 String module = settings.substitute(attributes.getValue("module"));
1135 module = module == null ? PatternMatcher.ANY_EXPRESSION : module;
1136 ArtifactId aid = new ArtifactId(new ModuleId(org, module), name, type, ext);
1137 Map extraAtt = ExtendableItemHelper.getExtraAttributes(settings, attributes,
1138 new String[] {"org", "module", "name", "type", "ext", "matcher", "conf"});
1139 confAware = new DefaultIncludeRule(aid, matcher, extraAtt);
1140 } else { // _state == ARTIFACT_EXCLUDE || EXCLUDE
1141 PatternMatcher matcher = getPatternMatcher(attributes.getValue("matcher"));
1142 String org = settings.substitute(attributes.getValue("org"));
1143 org = org == null ? PatternMatcher.ANY_EXPRESSION : org;
1144 String module = settings.substitute(attributes.getValue("module"));
1145 module = module == null ? PatternMatcher.ANY_EXPRESSION : module;
1146 ArtifactId aid = new ArtifactId(new ModuleId(org, module), name, type, ext);
1147 Map extraAtt = ExtendableItemHelper.getExtraAttributes(settings, attributes,
1148 new String[] {"org", "module", "name", "type", "ext", "matcher", "conf"});
1149 confAware = new DefaultExcludeRule(aid, matcher, extraAtt);
1118 if (ext == null) {
1119 ext = type;
1120 }
1121 switch (state) {
1122 case State.DEP_ARTIFACT: {
1123 String url = settings.substitute(attributes.getValue("url"));
1124 Map<String, String> extraAtt = ExtendableItemHelper.getExtraAttributes(settings,
1125 attributes, Arrays.asList("name", "type", "ext", "url", "conf"));
1126 confAware = new DefaultDependencyArtifactDescriptor(dd, name, type, ext,
1127 url == null ? null : new URL(url), extraAtt);
1128 break;
1129 }
1130 case State.ARTIFACT_INCLUDE: {
1131 PatternMatcher matcher = getPatternMatcher(attributes.getValue("matcher"));
1132 String org = settings.substitute(attributes.getValue("org"));
1133 if (org == null) {
1134 org = PatternMatcher.ANY_EXPRESSION;
1135 }
1136 String module = settings.substitute(attributes.getValue("module"));
1137 if (module == null) {
1138 module = PatternMatcher.ANY_EXPRESSION;
1139 }
1140 ArtifactId aid = new ArtifactId(new ModuleId(org, module), name, type, ext);
1141 Map<String, String> extraAtt = ExtendableItemHelper.getExtraAttributes(settings,
1142 attributes, Arrays.asList("org", "module", "name", "type", "ext", "matcher",
1143 "conf"));
1144 confAware = new DefaultIncludeRule(aid, matcher, extraAtt);
1145 break;
1146 }
1147 default: { // _state == ARTIFACT_EXCLUDE || EXCLUDE
1148 PatternMatcher matcher = getPatternMatcher(attributes.getValue("matcher"));
1149 String org = settings.substitute(attributes.getValue("org"));
1150 if (org == null) {
1151 org = PatternMatcher.ANY_EXPRESSION;
1152 }
1153 String module = settings.substitute(attributes.getValue("module"));
1154 if (module == null) {
1155 module = PatternMatcher.ANY_EXPRESSION;
1156 }
1157 ArtifactId aid = new ArtifactId(new ModuleId(org, module), name, type, ext);
1158 Map<String, String> extraAtt = ExtendableItemHelper.getExtraAttributes(settings,
1159 attributes, Arrays.asList("org", "module", "name", "type", "ext", "matcher",
1160 "conf"));
1161 confAware = new DefaultExcludeRule(aid, matcher, extraAtt);
1162 break;
1163 }
11501164 }
11511165 String confs = settings.substitute(attributes.getValue("conf"));
11521166 // only add confs if they are specified. if they aren't, endElement will handle this
11531167 // only if there are no conf defined in sub elements
11541168 if (confs != null && confs.length() > 0) {
1155 String[] conf;
1156 if ("*".equals(confs)) {
1157 conf = getMd().getConfigurationsNames();
1158 } else {
1159 conf = confs.split(",");
1160 }
1161 for (int i = 0; i < conf.length; i++) {
1162 addConfiguration(conf[i].trim());
1169 String[] configs = "*".equals(confs) ? getMd().getConfigurationsNames()
1170 : splitToArray(confs);
1171 for (String config : configs) {
1172 addConfiguration(config);
11631173 }
11641174 }
11651175 }
11671177 protected void addConfiguration(String c) {
11681178 confAware.addConfiguration(c);
11691179 if (state == State.EXCLUDE) {
1170 // we are adding a configuration to a module wide exclude rule
1171 // we have nothing special to do here, the rule has already been added to the module
1172 // descriptor
1180 // we are adding a configuration to a module wide exclude rule we have nothing
1181 // special to do here, the rule has already been added to the module descriptor
11731182 } else {
11741183 // we are currently adding a configuration to either an include, exclude or artifact
1175 // element
1176 // of a dependency. This means that we have to add this element to the corresponding
1177 // conf
1178 // of the current dependency descriptor
1184 // element of a dependency. This means that we have to add this element to the
1185 // corresponding conf of the current dependency descriptor
11791186 if (confAware instanceof DependencyArtifactDescriptor) {
11801187 dd.addDependencyArtifact(c, (DependencyArtifactDescriptor) confAware);
11811188 } else if (confAware instanceof IncludeRule) {
11961203 return matcher;
11971204 }
11981205
1206 @Override
11991207 public void characters(char[] ch, int start, int length) throws SAXException {
12001208 if (buffer != null) {
12011209 buffer.append(ch, start, length);
12021210 }
12031211 }
12041212
1213 @Override
12051214 public void endElement(String uri, String localName, String qName) throws SAXException {
12061215 if (state == State.PUB && "artifact".equals(qName)
12071216 && artifact.getConfigurations().length == 0) {
1208 String[] confs = publicationsDefaultConf == null ? getMd().getConfigurationsNames()
1209 : publicationsDefaultConf;
1210 for (int i = 0; i < confs.length; i++) {
1211 artifact.addConfiguration(confs[i].trim());
1212 getMd().addArtifact(confs[i].trim(), artifact);
1217 String[] configs = (publicationsDefaultConf == null)
1218 ? getMd().getConfigurationsNames() : publicationsDefaultConf;
1219 for (String config : configs) {
1220 artifact.addConfiguration(config);
1221 getMd().addArtifact(config, artifact);
12131222 }
12141223 } else if ("configurations".equals(qName)) {
12151224 checkConfigurations();
1216 } else if ((state == State.DEP_ARTIFACT && "artifact".equals(qName))
1217 || (state == State.ARTIFACT_INCLUDE && "include".equals(qName))
1218 || (state == State.ARTIFACT_EXCLUDE && "exclude".equals(qName))) {
1225 } else if (state == State.DEP_ARTIFACT && "artifact".equals(qName)
1226 || state == State.ARTIFACT_INCLUDE && "include".equals(qName)
1227 || state == State.ARTIFACT_EXCLUDE && "exclude".equals(qName)) {
12191228 state = State.DEP;
12201229 if (confAware.getConfigurations().length == 0) {
1221 String[] confs = getMd().getConfigurationsNames();
1222 for (int i = 0; i < confs.length; i++) {
1223 addConfiguration(confs[i]);
1230 for (String config : getMd().getConfigurationsNames()) {
1231 addConfiguration(config);
12241232 }
12251233 }
12261234 confAware = null;
12271235 } else if ("exclude".equals(qName) && state == State.EXCLUDE) {
12281236 if (confAware.getConfigurations().length == 0) {
1229 String[] confs = getMd().getConfigurationsNames();
1230 for (int i = 0; i < confs.length; i++) {
1231 addConfiguration(confs[i]);
1237 for (String config : getMd().getConfigurationsNames()) {
1238 addConfiguration(config);
12321239 }
12331240 }
12341241 confAware = null;
12631270 buffer.deleteCharAt(buffer.length() - 1);
12641271 buffer.append("/>");
12651272 } else {
1266 buffer.append("</" + qName + ">");
1273 buffer.append("</").append(qName).append(">");
12671274 }
12681275 }
12691276 }
12751282 }
12761283
12771284 protected void replaceConfigurationWildcards() {
1278 Configuration[] configs = getMd().getConfigurations();
1279 for (int i = 0; i < configs.length; i++) {
1280 configs[i].replaceWildcards(getMd());
1285 for (Configuration config : getMd().getConfigurations()) {
1286 config.replaceWildcards(getMd());
12811287 }
12821288 }
12831289
13461352 this.artifactsDeclared = artifactsDeclared;
13471353 }
13481354
1349 protected StringBuffer getBuffer() {
1355 protected StringBuilder getBuffer() {
13501356 return buffer;
13511357 }
13521358
1353 protected void setBuffer(StringBuffer buffer) {
1359 protected void setBuffer(StringBuilder buffer) {
13541360 this.buffer = buffer;
13551361 }
13561362
13791385 }
13801386 }
13811387
1388 @Override
13821389 public String toString() {
13831390 return "ivy parser";
13841391 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 import java.io.PrintWriter;
2727 import java.io.StringWriter;
2828 import java.net.URL;
29 import java.nio.charset.StandardCharsets;
2930 import java.util.ArrayList;
3031 import java.util.Arrays;
3132 import java.util.Collection;
3233 import java.util.Collections;
3334 import java.util.Date;
34 import java.util.Iterator;
3535 import java.util.LinkedHashMap;
3636 import java.util.List;
3737 import java.util.Map;
3838 import java.util.Stack;
39 import java.util.StringTokenizer;
4039
4140 import javax.xml.parsers.ParserConfigurationException;
4241
6665 import org.xml.sax.ext.LexicalHandler;
6766 import org.xml.sax.helpers.DefaultHandler;
6867
68 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
69 import static org.apache.ivy.util.StringUtils.joinArray;
70 import static org.apache.ivy.util.StringUtils.splitToArray;
71
6972 /**
7073 * Used to update ivy files. Uses ivy file as source and not ModuleDescriptor to preserve as much as
7174 * possible the original syntax
7376 public final class XmlModuleDescriptorUpdater {
7477 // CheckStyle:StaticVariableName| OFF
7578 // LINE_SEPARATOR is actually a constant, but we have to modify it for the tests
76 public static String LINE_SEPARATOR = System.getProperty("line.separator");
79 public static String LINE_SEPARATOR = System.lineSeparator();
7780
7881 // CheckStyle:StaticVariableName| ON
7982
8386 /**
8487 * used to copy a module descriptor xml file (also known as ivy file) and update the revisions
8588 * of its dependencies, its status and revision
86 *
89 *
8790 * @param srcURL
8891 * the url of the source module descriptor file
8992 * @param destFile
9093 * The file to which the updated module descriptor should be output
94 * @param options
95 * UpdateOptions
96 * @throws IOException if something goes wrong
97 * @throws SAXException if something goes wrong
9198 */
9299 public static void update(URL srcURL, File destFile, UpdateOptions options) throws IOException,
93100 SAXException {
158165 private static class UpdaterHandler extends DefaultHandler implements LexicalHandler {
159166
160167 /** standard attributes of ivy-module/info */
161 private static final Collection STD_ATTS = Arrays.asList(new String[] {"organisation",
162 "module", "branch", "revision", "status", "publication", "namespace"});
168 private static final Collection<String> STD_ATTS = Arrays.asList("organisation",
169 "module", "branch", "revision", "status", "publication", "namespace");
163170
164171 /** elements that may appear inside ivy-module, in expected order */
165 private static final List MODULE_ELEMENTS = Arrays.asList(new String[] {"info",
166 "configurations", "publications", "dependencies", "conflicts"});
172 private static final List<String> MODULE_ELEMENTS = Arrays.asList("info",
173 "configurations", "publications", "dependencies", "conflicts");
167174
168175 /** element position of "configurations" inside "ivy-module" */
169176 private static final int CONFIGURATIONS_POSITION = MODULE_ELEMENTS
173180 private static final int DEPENDENCIES_POSITION = MODULE_ELEMENTS.indexOf("dependencies");
174181
175182 /** elements that may appear inside of ivy-module/info */
176 private static final Collection INFO_ELEMENTS = Arrays.asList(new String[] {"extends",
177 "ivyauthor", "license", "repository", "description"});
183 private static final Collection<String> INFO_ELEMENTS = Arrays.asList("extends",
184 "ivyauthor", "license", "repository", "description");
178185
179186 private final ParserSettings settings;
180187
181188 private final PrintWriter out;
182189
183 private final Map resolvedRevisions;
184
185 private final Map resolvedBranches;
190 private final Map<ModuleRevisionId, String> resolvedRevisions;
191
192 private final Map<ModuleRevisionId, String> resolvedBranches;
186193
187194 private final String status;
188195
198205
199206 private boolean inHeader = true;
200207
201 private final List confs;
208 private final List<String> confs;
202209
203210 private final URL relativePathCtx;
204211
220227 if (options.getConfsToExclude() != null) {
221228 this.confs = Arrays.asList(options.getConfsToExclude());
222229 } else {
223 this.confs = Collections.EMPTY_LIST;
230 this.confs = Collections.emptyList();
224231 }
225232 }
226233
228235 // nor do we need do handle indentation, original one is maintained except for attributes
229236
230237 private String organisation = null;
238
239 // defaultConf of imported configurations, if any
240 private String defaultConf = null;
231241
232242 // defaultConfMapping of imported configurations, if any
233243 private String defaultConfMapping = null;
245255 // true when we're reading indent whitespace
246256 private boolean indenting;
247257
248 private StringBuffer currentIndent = new StringBuffer();
249
250 private ArrayList indentLevels = new ArrayList(); // ArrayList<String>
258 private StringBuilder currentIndent = new StringBuilder();
259
260 private List<String> indentLevels = new ArrayList<>(); // ArrayList<String>
251261
252262 // true if an ivy-module/info/description element has been found in the published descriptor
253263 private boolean hasDescription = false;
261271 // the new value of the defaultconf attribute on the publications tag
262272 private String newDefaultConf = null;
263273
264 private Stack context = new Stack();
265
266 private Stack buffers = new Stack();
267
268 private Stack confAttributeBuffers = new Stack();
274 private Stack<String> context = new Stack<>();
275
276 private Stack<ExtendedBuffer> buffers = new Stack<>();
277
278 private Stack<ExtendedBuffer> confAttributeBuffers = new Stack<>();
269279
270280 public void startElement(String uri, String localName, String qName, Attributes attributes)
271281 throws SAXException {
299309 // by an absolute path.
300310 includeStarted(attributes);
301311 } else if ("ivy-module/info/extends".equals(path)) {
312 if (options.isMerge()) {
313 ModuleDescriptor mergedDescriptor = options.getMergedDescriptor();
314 for (ExtendsDescriptor inheritedDescriptor : mergedDescriptor.getInheritedDescriptors()) {
315 ModuleDescriptor rprid = inheritedDescriptor.getParentMd();
316 if (rprid instanceof DefaultModuleDescriptor) {
317 DefaultModuleDescriptor defaultModuleDescriptor = (DefaultModuleDescriptor) rprid;
318 if (defaultModuleDescriptor.getDefaultConf() != null) {
319 defaultConf = defaultModuleDescriptor.getDefaultConf();
320 }
321 if (defaultModuleDescriptor.getDefaultConfMapping() != null) {
322 defaultConfMapping = defaultModuleDescriptor.getDefaultConfMapping();
323 }
324 if (defaultModuleDescriptor.isMappingOverride()) {
325 confMappingOverride = Boolean.TRUE;
326 }
327 }
328 }
329 }
302330 startExtends(attributes);
303331 } else if ("ivy-module/dependencies/dependency".equals(path)) {
304332 startElementInDependency(attributes);
305 } else if ("dependencies".equals(qName)) {
306 startDependencies(attributes);
307333 } else if ("ivy-module/configurations/conf".equals(path)) {
308334 startElementInConfigurationsConf(qName, attributes);
335 } else if ("dependencies".equals(qName) || "configurations".equals(qName)) {
336 startElementWithConfAttributes(qName, attributes);
309337 } else if ("ivy-module/publications/artifact/conf".equals(path)
310338 || "ivy-module/dependencies/dependency/conf".equals(path)
311339 || "ivy-module/dependencies/dependency/artifact/conf".equals(path)) {
312340 buffers.push(new ExtendedBuffer(getContext()));
313 ((ExtendedBuffer) confAttributeBuffers.peek()).setDefaultPrint(false);
341 confAttributeBuffers.peek().setDefaultPrint(false);
314342 String confName = substitute(settings, attributes.getValue("name"));
315343 if (!confs.contains(confName)) {
316 ((ExtendedBuffer) confAttributeBuffers.peek()).setPrint(true);
317 ((ExtendedBuffer) buffers.peek()).setPrint(true);
344 confAttributeBuffers.peek().setPrint(true);
345 buffers.peek().setPrint(true);
318346 write("<" + qName);
319347 for (int i = 0; i < attributes.getLength(); i++) {
320348 write(" " + attributes.getQName(i) + "=\""
327355 confAttributeBuffers.push(buffer);
328356 write("<" + qName);
329357 buffer.setDefaultPrint(attributes.getValue("conf") == null
330 && ((newDefaultConf == null) || (newDefaultConf.length() > 0)));
358 && (newDefaultConf == null || !newDefaultConf.isEmpty()));
331359 for (int i = 0; i < attributes.getLength(); i++) {
332360 String attName = attributes.getQName(i);
333361 if ("conf".equals(attName)) {
334362 String confName = substitute(settings, attributes.getValue("conf"));
335 String newConf = removeConfigurationsFromList(confName, confs);
336 if (newConf.length() > 0) {
337 write(" " + attributes.getQName(i) + "=\"" + newConf + "\"");
338 ((ExtendedBuffer) buffers.peek()).setPrint(true);
363 String newConf = removeConfigurationsFromList(confName);
364 if (!newConf.isEmpty()) {
365 write(" " + attName + "=\"" + newConf + "\"");
366 buffers.peek().setPrint(true);
339367 }
340368 } else {
341 write(" " + attributes.getQName(i) + "=\""
369 write(" " + attName + "=\""
342370 + substitute(settings, attributes.getValue(i)) + "\"");
343371 }
344372 }
352380 String attName = attributes.getQName(i);
353381 if ("conf".equals(attName)) {
354382 String confName = substitute(settings, attributes.getValue("conf"));
355 String newConf = removeConfigurationsFromList(confName, confs);
356 if (newConf.length() > 0) {
357 write(" " + attributes.getQName(i) + "=\"" + newConf + "\"");
358 ((ExtendedBuffer) buffers.peek()).setPrint(true);
383 String newConf = removeConfigurationsFromList(confName);
384 if (!newConf.isEmpty()) {
385 write(" " + attName + "=\"" + newConf + "\"");
386 buffers.peek().setPrint(true);
359387 }
360388 } else {
361 write(" " + attributes.getQName(i) + "=\""
389 write(" " + attName + "=\""
362390 + substitute(settings, attributes.getValue(i)) + "\"");
363391 }
364392 }
404432 String name = attributes.getQName(i);
405433 String value = null;
406434
407 if ("revision".equals(name)) {
408 // replace inline revision with resolved parent revision
409 ModuleDescriptor merged = options.getMergedDescriptor();
410 if (merged != null) {
411 ExtendsDescriptor[] parents = merged.getInheritedDescriptors();
412 for (int j = 0; value == null && j < parents.length; ++j) {
413 ModuleRevisionId resolvedId = parents[j].getResolvedParentRevisionId();
414 if (parentId.equals(resolvedId.getModuleId())) {
415 value = resolvedId.getRevision();
435 switch (name) {
436 case "organisation":
437 value = org;
438 break;
439 case "module":
440 value = module;
441 break;
442 case "revision":
443 // replace inline revision with resolved parent revision
444 ModuleDescriptor merged = options.getMergedDescriptor();
445 if (merged != null) {
446 for (ExtendsDescriptor parent : merged.getInheritedDescriptors()) {
447 ModuleRevisionId resolvedId = parent.getResolvedParentRevisionId();
448 if (parentId.equals(resolvedId.getModuleId())) {
449 value = resolvedId.getRevision();
450 if (value != null) {
451 break;
452 }
453 }
416454 }
417455 }
418 }
419 if (value == null) {
456 if (value == null) {
457 value = substitute(settings, attributes.getValue(i));
458 }
459 break;
460 default:
420461 value = substitute(settings, attributes.getValue(i));
421 }
422 } else if ("organisation".equals(name)) {
423 value = org;
424 } else if ("module".equals(name)) {
425 value = module;
426 } else {
427 value = substitute(settings, attributes.getValue(i));
462 break;
428463 }
429464 write(" " + name + "=\"" + value + "\"");
430465 }
434469 buffers.push(new ExtendedBuffer(getContext()));
435470 String confName = substitute(settings, attributes.getValue("name"));
436471 if (!confs.contains(confName)) {
437 ((ExtendedBuffer) buffers.peek()).setPrint(true);
472 buffers.peek().setPrint(true);
438473 String extend = substitute(settings, attributes.getValue("extends"));
439474 if (extend != null) {
440 for (StringTokenizer tok = new StringTokenizer(extend, ", "); tok
441 .hasMoreTokens();) {
442 String current = tok.nextToken();
443 if (confs.contains(current)) {
475 for (String tok : splitToArray(extend)) {
476 if (confs.contains(tok)) {
444477 throw new IllegalArgumentException(
445478 "Cannot exclude a configuration which is extended.");
446479 }
455488 }
456489 }
457490
458 private void startDependencies(Attributes attributes) {
491 private void startElementWithConfAttributes(String qName, Attributes attributes) {
459492 // copy
460 write("<dependencies");
493 write("<" + qName);
461494 for (int i = 0; i < attributes.getLength(); i++) {
462495 String attName = attributes.getQName(i);
463 if ("defaultconfmapping".equals(attName)) {
496 if ("defaultconf".equals(attName) || "defaultconfmapping".equals(attName)) {
464497 String newMapping = removeConfigurationsFromMapping(
465 substitute(settings, attributes.getValue("defaultconfmapping")), confs);
466 if (newMapping.length() > 0) {
467 write(" " + attributes.getQName(i) + "=\"" + newMapping + "\"");
498 substitute(settings, attributes.getValue(attName)));
499 if (!newMapping.isEmpty()) {
500 write(" " + attName + "=\"" + newMapping + "\"");
468501 }
469502 } else {
470 write(" " + attributes.getQName(i) + "=\""
503 write(" " + attName + "=\""
471504 + substitute(settings, attributes.getValue(i)) + "\"");
505 }
506 }
507 // add default conf if needed
508 if (defaultConf != null && attributes.getValue("defaultconf") == null) {
509 String newConf = removeConfigurationsFromMapping(defaultConf);
510 if (!newConf.isEmpty()) {
511 write(" defaultconf=\"" + newConf + "\"");
472512 }
473513 }
474514 // add default conf mapping if needed
475515 if (defaultConfMapping != null && attributes.getValue("defaultconfmapping") == null) {
476 String newMapping = removeConfigurationsFromMapping(defaultConfMapping, confs);
477 if (newMapping.length() > 0) {
516 String newMapping = removeConfigurationsFromMapping(defaultConfMapping);
517 if (!newMapping.isEmpty()) {
478518 write(" defaultconfmapping=\"" + newMapping + "\"");
479519 }
480520 }
490530 String attName = attributes.getQName(i);
491531 if ("defaultconf".equals(attName)) {
492532 newDefaultConf = removeConfigurationsFromList(
493 substitute(settings, attributes.getValue("defaultconf")), confs);
494 if (newDefaultConf.length() > 0) {
495 write(" " + attributes.getQName(i) + "=\"" + newDefaultConf + "\"");
533 substitute(settings, attributes.getValue("defaultconf")));
534 if (!newDefaultConf.isEmpty()) {
535 write(" " + attName + "=\"" + newDefaultConf + "\"");
496536 }
497537 } else {
498 write(" " + attributes.getQName(i) + "=\""
538 write(" " + attName + "=\""
499539 + substitute(settings, attributes.getValue(i)) + "\"");
500540 }
501541 }
505545 ExtendedBuffer buffer = new ExtendedBuffer(getContext());
506546 buffers.push(buffer);
507547 confAttributeBuffers.push(buffer);
508 buffer.setDefaultPrint(attributes.getValue("conf") == null
509 || attributes.getValue("conf").trim().length() == 0);
548 buffer.setDefaultPrint(isNullOrEmpty(attributes.getValue("conf")));
510549 write("<dependency");
511550 String org = substitute(settings, attributes.getValue("org"));
512 org = org == null ? organisation : org;
551 if (org == null) {
552 org = organisation;
553 }
513554 String module = substitute(settings, attributes.getValue("name"));
514555 String branch = substitute(settings, attributes.getValue("branch"));
515556 String branchConstraint = substitute(settings, attributes.getValue("branchConstraint"));
516 branchConstraint = branchConstraint == null ? branch : branchConstraint;
557 if (branchConstraint == null) {
558 branchConstraint = branch;
559 }
517560
518561 // look for the branch used in resolved revisions
519562 if (branch == null) {
521564 if (ns != null) {
522565 mid = NameSpaceHelper.transform(mid, ns.getToSystemTransformer());
523566 }
524 for (Iterator iter = resolvedRevisions.keySet().iterator(); iter.hasNext();) {
525 ModuleRevisionId mrid = (ModuleRevisionId) iter.next();
567 for (ModuleRevisionId mrid : resolvedRevisions.keySet()) {
526568 if (mrid.getModuleId().equals(mid)) {
527569 branch = mrid.getBranch();
528570 break;
532574
533575 String revision = substitute(settings, attributes.getValue("rev"));
534576 String revisionConstraint = substitute(settings, attributes.getValue("revConstraint"));
535 Map extraAttributes = ExtendableItemHelper.getExtraAttributes(settings, attributes,
577 Map<String, String> extraAttributes = ExtendableItemHelper.getExtraAttributes(settings, attributes,
536578 XmlModuleDescriptorParser.DEPENDENCY_REGULAR_ATTRIBUTES);
537579 ModuleRevisionId localMrid = ModuleRevisionId.newInstance(org, module, branch,
538580 revision, extraAttributes);
539 ModuleRevisionId systemMrid = ns == null ? localMrid : ns.getToSystemTransformer()
581 ModuleRevisionId systemMrid = (ns == null) ? localMrid : ns.getToSystemTransformer()
540582 .transform(localMrid);
541583
542 String newBranch = (String) resolvedBranches.get(systemMrid);
584 String newBranch = resolvedBranches.get(systemMrid);
543585
544586 for (int i = 0; i < attributes.getLength(); i++) {
545587 String attName = attributes.getQName(i);
546 if ("rev".equals(attName)) {
547 String rev = (String) resolvedRevisions.get(systemMrid);
548 if (rev != null) {
549 write(" rev=\"" + rev + "\"");
550 if (attributes.getIndex("branchConstraint") == -1
551 && branchConstraint != null) {
552 write(" branchConstraint=\"" + branchConstraint + "\"");
588 switch (attName) {
589 case "org":
590 write(" org=\"" + systemMrid.getOrganisation() + "\"");
591 break;
592 case "name":
593 write(" name=\"" + systemMrid.getName() + "\"");
594 break;
595 case "rev":
596 String rev = resolvedRevisions.get(systemMrid);
597 if (rev == null) {
598 write(" rev=\"" + systemMrid.getRevision() + "\"");
599 } else {
600 write(" rev=\"" + rev + "\"");
601 if (attributes.getIndex("branchConstraint") == -1
602 && branchConstraint != null) {
603 write(" branchConstraint=\"" + branchConstraint + "\"");
604 }
605 if (generateRevConstraint && attributes.getIndex("revConstraint") == -1
606 && !rev.equals(systemMrid.getRevision())) {
607 write(" revConstraint=\"" + systemMrid.getRevision() + "\"");
608 }
553609 }
554 if (generateRevConstraint && attributes.getIndex("revConstraint") == -1
555 && !rev.equals(systemMrid.getRevision())) {
556 write(" revConstraint=\"" + systemMrid.getRevision() + "\"");
610 break;
611 case "revConstraint":
612 write(" revConstraint=\"" + revisionConstraint + "\"");
613 break;
614 case "branch":
615 if (newBranch != null) {
616 write(" branch=\"" + newBranch + "\"");
617 } else if (!resolvedBranches.containsKey(systemMrid)) {
618 write(" branch=\"" + systemMrid.getBranch() + "\"");
619 } else {
620 // if resolvedBranches contains the systemMrid, but the new branch is null,
621 // the branch attribute will be removed altogether
557622 }
558 } else {
559 write(" rev=\"" + systemMrid.getRevision() + "\"");
560 }
561 } else if ("revConstraint".equals(attName)) {
562 write(" revConstraint=\"" + revisionConstraint + "\"");
563 } else if ("org".equals(attName)) {
564 write(" org=\"" + systemMrid.getOrganisation() + "\"");
565 } else if ("name".equals(attName)) {
566 write(" name=\"" + systemMrid.getName() + "\"");
567 } else if ("branch".equals(attName)) {
568 if (newBranch != null) {
569 write(" branch=\"" + newBranch + "\"");
570 } else if (!resolvedBranches.containsKey(systemMrid)) {
571 write(" branch=\"" + systemMrid.getBranch() + "\"");
572 } else {
573 // if resolvedBranches contains the systemMrid, but the new branch is null,
574 // the branch attribute will be removed altogether
575 }
576 } else if ("branchConstraint".equals(attName)) {
577 write(" branchConstraint=\"" + branchConstraint + "\"");
578 } else if ("conf".equals(attName)) {
579 String oldMapping = substitute(settings, attributes.getValue("conf"));
580 if (oldMapping.length() > 0) {
581 String newMapping = removeConfigurationsFromMapping(oldMapping, confs);
582 if (newMapping.length() > 0) {
583 write(" conf=\"" + newMapping + "\"");
584 ((ExtendedBuffer) buffers.peek()).setPrint(true);
623 break;
624 case "branchConstraint":
625 write(" branchConstraint=\"" + branchConstraint + "\"");
626 break;
627 case "conf":
628 String oldMapping = substitute(settings, attributes.getValue("conf"));
629 if (!oldMapping.isEmpty()) {
630 String newMapping = removeConfigurationsFromMapping(oldMapping);
631 if (!newMapping.isEmpty()) {
632 write(" conf=\"" + newMapping + "\"");
633 buffers.peek().setPrint(true);
634 }
585635 }
586 }
587 } else {
588 write(" " + attName + "=\""
589 + substitute(settings, attributes.getValue(attName)) + "\"");
636 break;
637 default:
638 write(" " + attName + "=\""
639 + substitute(settings, attributes.getValue(attName)) + "\"");
640 break;
590641 }
591642 }
592643
593644 if (attributes.getIndex("branch") == -1) {
594 if (newBranch != null) {
595 // erase an existing branch attribute if its new value is blank
596 if (!newBranch.trim().equals("")) {
597 write(" branch=\"" + newBranch + "\"");
598 }
645 // erase an existing branch attribute if its new value is blank
646 if (!isNullOrEmpty(newBranch)) {
647 write(" branch=\"" + newBranch + "\"");
599648 } else if (options.isUpdateBranch() && systemMrid.getBranch() != null) {
600649 // this dependency is on a specific branch, we set it explicitly in the updated
601650 // file
609658 buffers.push(buffer);
610659 try {
611660 URL url;
612 if (settings != null) {
613 url = settings.getRelativeUrlResolver().getURL(relativePathCtx,
614 settings.substitute(attributes.getValue("file")),
615 settings.substitute(attributes.getValue("url")));
616 } else {
661 if (settings == null) {
617662 // TODO : settings can be null, but I don't why.
618 // Check if the next code is correct in that case
663 // Check if the following code is correct in that case
619664 String fileName = attributes.getValue("file");
620665 if (fileName == null) {
621666 String urlStr = attributes.getValue("url");
623668 } else {
624669 url = Checks.checkAbsolute(fileName, "settings.include").toURI().toURL();
625670 }
671 } else {
672 url = settings.getRelativeUrlResolver().getURL(relativePathCtx,
673 settings.substitute(attributes.getValue("file")),
674 settings.substitute(attributes.getValue("url")));
626675 }
627676 XMLHelper.parse(url, null, new DefaultHandler() {
628677 private boolean insideConfigurations = false;
634683 if ("configurations".equals(qName)) {
635684 insideConfigurations = true;
636685 String defaultconf = substitute(settings,
686 attributes.getValue("defaultconf"));
687 if (defaultconf != null) {
688 defaultConf = defaultconf;
689 }
690 String defaultMapping = substitute(settings,
637691 attributes.getValue("defaultconfmapping"));
638 if (defaultconf != null) {
639 defaultConfMapping = defaultconf;
692 if (defaultMapping != null) {
693 defaultConfMapping = defaultMapping;
640694 }
641695 String mappingOverride = substitute(settings,
642696 attributes.getValue("confmappingoverride"));
652706 }
653707 String extend = substitute(settings, attributes.getValue("extends"));
654708 if (extend != null) {
655 for (StringTokenizer tok = new StringTokenizer(extend, ", "); tok
656 .hasMoreTokens();) {
657 String current = tok.nextToken();
658 if (confs.contains(current)) {
659 throw new IllegalArgumentException("Cannot exclude a "
660 + "configuration which is extended.");
709 for (String tok : splitToArray(extend)) {
710 if (confs.contains(tok)) {
711 throw new IllegalArgumentException(
712 "Cannot exclude a configuration which is extended.");
661713 }
662714 }
663
664715 }
665716
666717 write("<" + qName);
693744 String branch = null;
694745 String status = null;
695746 String namespace = null;
696 Map/* <String,String> */extraAttributes = null;
747 Map<String, String> extraAttributes = null;
697748
698749 if (options.isMerge()) {
699750 // get attributes from merged descriptor, ignoring raw XML
724775 branch = substitute(settings, attributes.getValue("branch"));
725776 status = substitute(settings, attributes.getValue("status"));
726777 namespace = substitute(settings, attributes.getValue("namespace"));
727 extraAttributes = new LinkedHashMap(attributes.getLength());
778 extraAttributes = new LinkedHashMap<>(attributes.getLength());
728779 for (int i = 0; i < attributes.getLength(); i++) {
729780 String qname = attributes.getQName(i);
730781 if (!STD_ATTS.contains(qname)) {
746797
747798 // if necessary translate mrid using optional namespace argument
748799 ModuleRevisionId localMid = ModuleRevisionId.newInstance(organisation, module, branch,
749 rev, ExtendableItemHelper
750 .getExtraAttributes(settings, attributes, new String[] {"organisation",
751 "module", "revision", "status", "publication", "namespace"}));
752 ModuleRevisionId systemMid = ns == null ? localMid : ns.getToSystemTransformer()
800 rev, ExtendableItemHelper.getExtraAttributes(settings, attributes,
801 Arrays.asList("organisation", "module", "revision", "status",
802 "publication", "namespace")));
803 ModuleRevisionId systemMid = (ns == null) ? localMid : ns.getToSystemTransformer()
753804 .transform(localMid);
754805
755806 write("<info");
774825 write(" namespace=\"" + namespace + "\"");
775826 }
776827
777 for (Iterator extras = extraAttributes.entrySet().iterator(); extras.hasNext();) {
778 Map.Entry extra = (Map.Entry) extras.next();
828 for (Map.Entry<String, String> extra : extraAttributes.entrySet()) {
779829 write(" " + extra.getKey() + "=\"" + extra.getValue() + "\"");
780830 }
781831 }
785835 }
786836
787837 private PrintWriter getWriter() {
788 return buffers.isEmpty() ? out : ((ExtendedBuffer) buffers.peek()).getWriter();
838 return buffers.isEmpty() ? out : buffers.peek().getWriter();
789839 }
790840
791841 private String getContext() {
792 StringBuffer buf = new StringBuffer();
793 for (Iterator iter = context.iterator(); iter.hasNext();) {
794 String ctx = (String) iter.next();
795 buf.append(ctx).append("/");
796 }
797 if (buf.length() > 0) {
798 buf.setLength(buf.length() - 1);
799 }
800 return buf.toString();
842 return joinArray(context.toArray(new String[context.size()]), "/");
801843 }
802844
803845 private String substitute(ParserSettings ivy, String value) {
804 String result = ivy == null ? value : ivy.substitute(value);
846 String result = (ivy == null) ? value : ivy.substitute(value);
805847 return XMLHelper.escape(result);
806848 }
807849
808 private String removeConfigurationsFromMapping(String mapping, List confsToRemove) {
809 StringBuffer newMapping = new StringBuffer();
850 private String removeConfigurationsFromMapping(String mapping) {
851 StringBuilder newMapping = new StringBuilder();
810852 String mappingSep = "";
811 for (StringTokenizer tokenizer = new StringTokenizer(mapping, ";"); tokenizer
812 .hasMoreTokens();) {
813 String current = tokenizer.nextToken();
814 String[] ops = current.split("->");
815 String[] lhs = ops[0].split(",");
816 List confsToWrite = new ArrayList();
817 for (int j = 0; j < lhs.length; j++) {
818 if (!confs.contains(lhs[j].trim())) {
819 confsToWrite.add(lhs[j]);
853 for (String groups : mapping.trim().split("\\s*;\\s*")) {
854 String[] ops = groups.split("->");
855 List<String> confsToWrite = new ArrayList<>();
856 for (String lh : splitToArray(ops[0])) {
857 if (!confs.contains(lh)) {
858 confsToWrite.add(lh);
820859 }
821860 }
822861 if (!confsToWrite.isEmpty()) {
823862 newMapping.append(mappingSep);
824
825863 String sep = "";
826 for (Iterator it = confsToWrite.iterator(); it.hasNext();) {
827 newMapping.append(sep);
828 newMapping.append(it.next());
829 sep = ",";
864 String listSep = groups.contains(", ") ? ", " : ",";
865 for (String confToWrite : confsToWrite) {
866 newMapping.append(sep).append(confToWrite);
867 sep = listSep;
830868 }
831869 if (ops.length == 2) {
832 newMapping.append("->");
833 newMapping.append(ops[1]);
870 newMapping.append("->").append(joinArray(splitToArray(ops[1]), sep));
834871 }
835872 mappingSep = ";";
836873 }
837874 }
838
839875 return newMapping.toString();
840876 }
841877
842 private String removeConfigurationsFromList(String list, List confsToRemove) {
843 StringBuffer newList = new StringBuffer();
844 String listSep = "";
845 for (StringTokenizer tokenizer = new StringTokenizer(list, ","); tokenizer
846 .hasMoreTokens();) {
847 String current = tokenizer.nextToken();
848 if (!confsToRemove.contains(current.trim())) {
849 newList.append(listSep);
850 newList.append(current);
851 listSep = ",";
852 }
853 }
854
878 private String removeConfigurationsFromList(String list) {
879 StringBuilder newList = new StringBuilder();
880 String sep = "";
881 String listSep = list.contains(", ") ? ", " : ",";
882 for (String current : splitToArray(list)) {
883 if (!confs.contains(current)) {
884 newList.append(sep).append(current);
885 sep = listSep;
886 }
887 }
855888 return newList.toString();
856889 }
857890
913946 // add a default single-level indent until we see indents in the document
914947 indentLevels.add(" ");
915948 }
916 String oneLevel = (String) indentLevels.get(0);
949 String oneLevel = indentLevels.get(0);
917950 for (int fill = indentLevels.size(); fill <= level; ++fill) {
918951 indentLevels.add(indentLevels.get(fill - 1) + oneLevel);
919952 }
920953 }
921954
922 /** get the whitespace that should precede new elements at the current depth in the document */
955 /**
956 * get the whitespace that should precede new elements at the current depth in the document
957 */
923958 private String getIndent() {
924959 int level = context.size() - 1;
925960 fillIndents(level);
926 return (String) indentLevels.get(level);
961 return indentLevels.get(level);
927962 }
928963
929964 /**
930965 * Write XML elements that do not appear in the source descriptor, but have been copied in
931966 * from a parent module descriptor via &lt;extends&gt; declaration.
932 *
967 *
933968 * @param merged
934969 * child descriptor containing the merged data
935970 * @param items
949984 // we can add some useful comments
950985 PrintWriter out = getWriter();
951986
952 Map inheritedItems = collateInheritedItems(merged, items);
987 Map<ModuleRevisionId, List<InheritableItem>> inheritedItems = collateInheritedItems(
988 merged, items);
953989 boolean hasItems = !inheritedItems.isEmpty();
954990
955991 if (hasItems && includeContainer) {
956992 if (currentIndent.length() == 0) {
957993 out.print(getIndent());
958994 }
959 out.print("<" + itemName + ">");
995 String newConf = (defaultConf == null) ? ""
996 : removeConfigurationsFromMapping(defaultConf);
997 String newMapping = (defaultConfMapping == null) ? ""
998 : removeConfigurationsFromMapping(defaultConfMapping);
999 out.print(String.format("<%s%s%s%s>", itemName,
1000 newConf.isEmpty() ? "" : " defaultconf=\"" + newConf + "\"",
1001 newMapping.isEmpty() ? "" : " defaultconfmapping=\"" + newMapping + "\"",
1002 (confMappingOverride != null) ? " confmappingoverride=\"" + confMappingOverride + "\"" : ""));
9601003 context.push(itemName);
9611004 justOpen = null;
9621005 }
9631006
964 for (Iterator parents = inheritedItems.entrySet().iterator(); parents.hasNext();) {
965 Map.Entry entry = (Map.Entry) parents.next();
966 ModuleRevisionId parent = (ModuleRevisionId) entry.getKey();
967 List list = (List) entry.getValue();
968
1007 for (Map.Entry<ModuleRevisionId, List<InheritableItem>> entry : inheritedItems
1008 .entrySet()) {
9691009 if (justOpen != null) {
9701010 out.println(">");
9711011 justOpen = null; // helps endElement() decide how to write close tags
9721012 }
973 writeInheritanceComment(itemName, parent);
974 for (int c = 0; c < list.size(); ++c) {
975 InheritableItem item = (InheritableItem) list.get(c);
1013 writeInheritanceComment(itemName, entry.getKey());
1014 for (InheritableItem item : entry.getValue()) {
9761015 out.print(getIndent());
9771016 printer.print(merged, item, out);
9781017 }
10001039 * Collect the given list of inherited descriptor items into lists keyed by parent Id. Thus
10011040 * all of the items inherited from parent A can be written together, then all of the items
10021041 * from parent B, and so on.
1003 *
1042 *
10041043 * @param merged
10051044 * the merged child descriptor
10061045 * @param items
10081047 * @return maps parent ModuleRevisionId to a List of InheritedItems imported from that
10091048 * parent
10101049 */
1011 private Map/* <ModuleRevisionId,List> */collateInheritedItems(ModuleDescriptor merged,
1012 InheritableItem[] items) {
1013 LinkedHashMap/* <ModuleRevisionId,List> */inheritedItems = new LinkedHashMap();
1014 for (int i = 0; i < items.length; ++i) {
1015 ModuleRevisionId source = items[i].getSourceModule();
1050 private Map<ModuleRevisionId, List<InheritableItem>> collateInheritedItems(
1051 ModuleDescriptor merged, InheritableItem[] items) {
1052 Map<ModuleRevisionId, List<InheritableItem>> inheritedItems = new LinkedHashMap<>();
1053 for (InheritableItem item : items) {
1054 ModuleRevisionId source = item.getSourceModule();
10161055 // ignore items that are defined directly in the child descriptor
10171056 if (source != null
10181057 && !source.getModuleId().equals(merged.getModuleRevisionId().getModuleId())) {
1019 List accum = (List) inheritedItems.get(source);
1058 List<InheritableItem> accum = inheritedItems.get(source);
10201059 if (accum == null) {
1021 accum = new ArrayList();
1060 accum = new ArrayList<>();
10221061 inheritedItems.put(source, accum);
10231062 }
1024 accum.add(items[i]);
1063 accum.add(item);
10251064 }
10261065 }
10271066 return inheritedItems;
10351074 if (!hasDescription) {
10361075 hasDescription = true;
10371076 String description = merged.getDescription();
1038 if ((description != null) && (description.length() > 0)) {
1077 if (!isNullOrEmpty(description)) {
10391078 PrintWriter writer = getWriter();
10401079 if (justOpen != null) {
10411080 writer.println(">");
10741113 * elements like "configurations" and "dependencies" appear in the parent descriptor, but
10751114 * are completely missing in the child descriptor.
10761115 * </p>
1077 *
1116 *
10781117 * <p>
10791118 * For example, if "moduleElement" is "dependencies", guarantees that "configurations" has
10801119 * been written. If <code>moduleElement</code> is <code>null</code>, then all missing merged
10811120 * elements will be flushed.
10821121 * </p>
1083 *
1122 *
10841123 * @param moduleElement
10851124 * a descriptor element name, for example "configurations" or "info"
10861125 */
10891128 && !(mergedConfigurations && mergedDependencies)) {
10901129
10911130 // calculate the position of the element in ivy-module
1092 int position = moduleElement == null ? MODULE_ELEMENTS.size() : MODULE_ELEMENTS
1093 .indexOf(moduleElement);
1131 int position = (moduleElement == null) ? MODULE_ELEMENTS.size()
1132 : MODULE_ELEMENTS.indexOf(moduleElement);
10941133
10951134 ModuleDescriptor merged = options.getMergedDescriptor();
10961135
11241163 String path = getContext();
11251164 if (options.isMerge()) {
11261165 ModuleDescriptor merged = options.getMergedDescriptor();
1127
1128 if ("ivy-module/info".equals(path)) {
1129 // guarantee that inherited description has been written before
1130 // info element closes.
1131 writeInheritedDescription(merged);
1132 } else if ("ivy-module/configurations".equals(path)) {
1133 // write inherited configurations after all child configurations
1134 writeInheritedConfigurations(merged);
1135 } else if ("ivy-module/dependencies".equals(path)) {
1136 // write inherited dependencies after all child dependencies
1137 writeInheritedDependencies(merged);
1138 } else if ("ivy-module".equals(path)) {
1139 // write any remaining inherited data before we close the
1140 // descriptor.
1141 flushAllMergedElements();
1166 switch (path) {
1167 case "ivy-module/info":
1168 // guarantee that inherited description has been written before
1169 // info element closes.
1170 writeInheritedDescription(merged);
1171 break;
1172 case "ivy-module/configurations":
1173 // write inherited configurations after all child configurations
1174 writeInheritedConfigurations(merged);
1175 break;
1176 case "ivy-module/dependencies":
1177 // write inherited dependencies after all child dependencies
1178 writeInheritedDependencies(merged);
1179 break;
1180 case "ivy-module":
1181 // write any remaining inherited data before we close the
1182 // descriptor.
1183 flushAllMergedElements();
1184 break;
11421185 }
11431186 }
11441187
11491192 }
11501193
11511194 if (!buffers.isEmpty()) {
1152 ExtendedBuffer buffer = (ExtendedBuffer) buffers.peek();
1195 ExtendedBuffer buffer = buffers.peek();
11531196 if (buffer.getContext().equals(path)) {
11541197 buffers.pop();
11551198 if (buffer.isPrint()) {
11591202 }
11601203
11611204 if (!confAttributeBuffers.isEmpty()) {
1162 ExtendedBuffer buffer = (ExtendedBuffer) confAttributeBuffers.peek();
1205 ExtendedBuffer buffer = confAttributeBuffers.peek();
11631206 if (buffer.getContext().equals(path)) {
11641207 confAttributeBuffers.pop();
11651208 }
12161259 justOpen = null;
12171260 }
12181261
1219 StringBuffer comment = new StringBuffer();
1220 comment.append(ch, start, length);
12211262 write("<!--");
1222 write(comment.toString());
1263 write(String.valueOf(ch, start, length));
12231264 write("-->");
12241265
12251266 if (inHeader) {
12401281
12411282 public static void update(URL inStreamCtx, InputStream inStream, OutputStream outStream,
12421283 final UpdateOptions options) throws IOException, SAXException {
1243 final PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, "UTF-8"));
1284 final PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, StandardCharsets.UTF_8));
12441285 out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
12451286 out.write(LINE_SEPARATOR);
12461287
12521293 }
12531294 XMLHelper.parse(inSrc, null, updaterHandler, updaterHandler);
12541295 } catch (ParserConfigurationException e) {
1255 IllegalStateException ise = new IllegalStateException(
1256 "impossible to update Ivy files: parser problem");
1257 ise.initCause(e);
1258 throw ise;
1296 throw new IllegalStateException("impossible to update Ivy files: parser problem", e);
12591297 }
12601298 }
12611299
12781316 if (print == null) {
12791317 return defaultPrint;
12801318 }
1281 return print.booleanValue();
1319 return print;
12821320 }
12831321
12841322 void setPrint(boolean print) {
1285 this.print = Boolean.valueOf(print);
1323 this.print = print;
12861324 }
12871325
12881326 void setDefaultPrint(boolean print) {
13061344 /**
13071345 * Prints a descriptor item's XML representation
13081346 */
1309 protected static interface ItemPrinter {
1347 protected interface ItemPrinter {
13101348 /**
13111349 * Print an XML representation of <code>item</code> to <code>out</code>.
1312 *
1350 *
13131351 * @param parent
13141352 * the module descriptor containing <code>item</code>
13151353 * @param item
13161354 * subcomponent of the descriptor, for example a {@link DependencyDescriptor} or
13171355 * {@link Configuration}
1356 * @param out PrintWriter
13181357 */
1319 public void print(ModuleDescriptor parent, Object item, PrintWriter out);
1358 void print(ModuleDescriptor parent, Object item, PrintWriter out);
13201359 }
13211360
13221361 protected static class DependencyPrinter implements ItemPrinter {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.io.IOException;
2222 import java.io.OutputStreamWriter;
2323 import java.io.PrintWriter;
24 import java.nio.charset.StandardCharsets;
2425 import java.util.Arrays;
25 import java.util.Iterator;
2626 import java.util.Map;
27 import java.util.Map.Entry;
2827
2928 import org.apache.ivy.core.IvyPatternHelper;
3029 import org.apache.ivy.core.module.descriptor.Artifact;
4443 import org.apache.ivy.plugins.matcher.MapMatcher;
4544 import org.apache.ivy.util.DateUtil;
4645 import org.apache.ivy.util.Message;
47 import org.apache.ivy.util.StringUtils;
4846 import org.apache.ivy.util.XMLHelper;
4947 import org.apache.ivy.util.extendable.ExtendableItem;
48
49 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
50 import static org.apache.ivy.util.StringUtils.joinArray;
5051
5152 /**
5253 *
6667 if (output.getParentFile() != null) {
6768 output.getParentFile().mkdirs();
6869 }
69 PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output),
70 "UTF-8"));
71 try {
70 try (PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(output),
71 StandardCharsets.UTF_8))) {
7272 out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
7373 if (licenseHeader != null) {
7474 out.print(licenseHeader);
7575 }
76 StringBuffer xmlNamespace = new StringBuffer();
77 Map namespaces = md.getExtraAttributesNamespaces();
78 for (Iterator iter = namespaces.entrySet().iterator(); iter.hasNext();) {
79 Entry ns = (Entry) iter.next();
76 StringBuilder xmlNamespace = new StringBuilder();
77 Map<String, String> namespaces = md.getExtraAttributesNamespaces();
78 for (Map.Entry<String, String> ns : namespaces.entrySet()) {
8079 xmlNamespace.append(" xmlns:").append(ns.getKey()).append("=\"")
8180 .append(ns.getValue()).append("\"");
8281 }
9291 printPublications(md, out);
9392 printDependencies(md, out);
9493 out.println("</ivy-module>");
95 } finally {
96 out.close();
9794 }
9895 }
9996
10198 DependencyDescriptor[] dds = md.getDependencies();
10299 if (dds.length > 0) {
103100 out.println("\t<dependencies>");
104 for (int i = 0; i < dds.length; i++) {
105 DependencyDescriptor dep = dds[i];
101 for (DependencyDescriptor dep : dds) {
106102 out.print("\t\t");
107103 printDependency(md, dep, out);
108104 }
114110
115111 protected static void printDependency(ModuleDescriptor md, DependencyDescriptor dep,
116112 PrintWriter out) {
117 out.print("<dependency");
118 out.print(" org=\"" + XMLHelper.escape(dep.getDependencyRevisionId().getOrganisation())
119 + "\"");
120 out.print(" name=\"" + XMLHelper.escape(dep.getDependencyRevisionId().getName()) + "\"");
121 if (dep.getDependencyRevisionId().getBranch() != null) {
122 out.print(" branch=\"" + XMLHelper.escape(dep.getDependencyRevisionId().getBranch())
123 + "\"");
124 }
125 out.print(" rev=\"" + XMLHelper.escape(dep.getDependencyRevisionId().getRevision()) + "\"");
126 if (!dep.getDynamicConstraintDependencyRevisionId().equals(dep.getDependencyRevisionId())) {
127 if (dep.getDynamicConstraintDependencyRevisionId().getBranch() != null) {
113 final ModuleRevisionId dependencyRevisionId = dep.getDependencyRevisionId();
114 out.print(String.format("<dependency org=\"%s\" name=\"%s\"",
115 XMLHelper.escape(dependencyRevisionId.getOrganisation()),
116 XMLHelper.escape(dependencyRevisionId.getName())));
117 if (dependencyRevisionId.getBranch() != null) {
118 out.print(" branch=\"" + XMLHelper.escape(dependencyRevisionId.getBranch()) + "\"");
119 }
120 out.print(" rev=\"" + XMLHelper.escape(dependencyRevisionId.getRevision()) + "\"");
121 final ModuleRevisionId dynamicConstraintDependencyRevisionId =
122 dep.getDynamicConstraintDependencyRevisionId();
123 if (!dynamicConstraintDependencyRevisionId.equals(dependencyRevisionId)) {
124 if (dynamicConstraintDependencyRevisionId.getBranch() != null) {
128125 out.print(" branchConstraint=\""
129 + XMLHelper.escape(dep.getDynamicConstraintDependencyRevisionId()
130 .getBranch()) + "\"");
126 + XMLHelper.escape(dynamicConstraintDependencyRevisionId.getBranch())
127 + "\"");
131128 }
132129 out.print(" revConstraint=\""
133 + XMLHelper
134 .escape(dep.getDynamicConstraintDependencyRevisionId().getRevision())
130 + XMLHelper.escape(dynamicConstraintDependencyRevisionId.getRevision())
135131 + "\"");
136132 }
137133 if (dep.isForce()) {
143139 if (!dep.isTransitive()) {
144140 out.print(" transitive=\"" + dep.isTransitive() + "\"");
145141 }
146 out.print(" conf=\"");
147 String[] modConfs = dep.getModuleConfigurations();
148 for (int j = 0; j < modConfs.length; j++) {
149 String[] depConfs = dep.getDependencyConfigurations(modConfs[j]);
150 out.print(XMLHelper.escape(modConfs[j]) + "->");
151 for (int k = 0; k < depConfs.length; k++) {
152 out.print(XMLHelper.escape(depConfs[k]));
153 if (k + 1 < depConfs.length) {
154 out.print(",");
155 }
156 }
157 if (j + 1 < modConfs.length) {
158 out.print(";");
159 }
160 }
161 out.print("\"");
142 StringBuilder sb = new StringBuilder();
143 for (String modConf : dep.getModuleConfigurations()) {
144 if (sb.length() > 0) {
145 sb.append(";");
146 }
147 sb.append(XMLHelper.escape(modConf)).append(
148 listToPrefixedString(dep.getDependencyConfigurations(modConf), "->"));
149 }
150 out.print(" conf=\"" + sb + "\"");
162151
163152 printExtraAttributes(dep, out, " ");
164153
187176 }
188177
189178 private static void printAllMediators(ModuleDescriptor md, PrintWriter out) {
190 Map/* <MapMatcher, DependencyDescriptorMediator> */mediators = md
179 Map<MapMatcher, DependencyDescriptorMediator> mediators = md
191180 .getAllDependencyDescriptorMediators().getAllRules();
192181
193 for (Iterator iterator = mediators.entrySet().iterator(); iterator.hasNext();) {
194 Map.Entry mediatorRule = (Map.Entry) iterator.next();
195 MapMatcher matcher = (MapMatcher) mediatorRule.getKey();
196 DependencyDescriptorMediator mediator = (DependencyDescriptorMediator) mediatorRule
197 .getValue();
182 for (Map.Entry<MapMatcher, DependencyDescriptorMediator> mediatorRule : mediators.entrySet()) {
183 MapMatcher matcher = mediatorRule.getKey();
184 DependencyDescriptorMediator mediator = mediatorRule.getValue();
198185
199186 if (mediator instanceof OverrideDependencyDescriptorMediator) {
200187 OverrideDependencyDescriptorMediator oddm = (OverrideDependencyDescriptorMediator) mediator;
201188
202 out.print("\t\t<override");
203 out.print(" org=\""
204 + XMLHelper.escape((String) matcher.getAttributes().get(
205 IvyPatternHelper.ORGANISATION_KEY)) + "\"");
206 out.print(" module=\""
207 + XMLHelper.escape((String) matcher.getAttributes().get(
208 IvyPatternHelper.MODULE_KEY)) + "\"");
209 out.print(" matcher=\"" + XMLHelper.escape(matcher.getPatternMatcher().getName())
210 + "\"");
189 out.print(String.format("\t\t<override org=\"%s\" module=\"%s\" matcher=\"%s\"",
190 XMLHelper.escape(matcher.getAttributes().get(IvyPatternHelper.ORGANISATION_KEY)),
191 XMLHelper.escape(matcher.getAttributes().get(IvyPatternHelper.MODULE_KEY)),
192 XMLHelper.escape(matcher.getPatternMatcher().getName())
193 ));
211194 if (oddm.getBranch() != null) {
212195 out.print(" branch=\"" + XMLHelper.escape(oddm.getBranch()) + "\"");
213196 }
225208 private static void printAllExcludes(ModuleDescriptor md, PrintWriter out) {
226209 ExcludeRule[] excludes = md.getAllExcludeRules();
227210 if (excludes.length > 0) {
228 for (int j = 0; j < excludes.length; j++) {
229 out.print("\t\t<exclude");
230 out.print(" org=\""
231 + XMLHelper.escape(excludes[j].getId().getModuleId().getOrganisation())
232 + "\"");
233 out.print(" module=\""
234 + XMLHelper.escape(excludes[j].getId().getModuleId().getName()) + "\"");
235 out.print(" artifact=\"" + XMLHelper.escape(excludes[j].getId().getName()) + "\"");
236 out.print(" type=\"" + XMLHelper.escape(excludes[j].getId().getType()) + "\"");
237 out.print(" ext=\"" + XMLHelper.escape(excludes[j].getId().getExt()) + "\"");
238 String[] ruleConfs = excludes[j].getConfigurations();
211 for (ExcludeRule exclude : excludes) {
212 out.print(String.format("\t\t<exclude org=\"%s\" module=\"%s\" artifact=\"%s\" type=\"%s\" ext=\"%s\"",
213 XMLHelper.escape(exclude.getId().getModuleId().getOrganisation()),
214 XMLHelper.escape(exclude.getId().getModuleId().getName()),
215 XMLHelper.escape(exclude.getId().getName()),
216 XMLHelper.escape(exclude.getId().getType()),
217 XMLHelper.escape(exclude.getId().getExt())));
218 String[] ruleConfs = exclude.getConfigurations();
239219 if (!Arrays.asList(ruleConfs).equals(Arrays.asList(md.getConfigurationsNames()))) {
240 out.print(" conf=\"");
241 for (int k = 0; k < ruleConfs.length; k++) {
242 out.print(XMLHelper.escape(ruleConfs[k]));
243 if (k + 1 < ruleConfs.length) {
244 out.print(",");
245 }
246 }
247 out.print("\"");
248 }
249 out.print(" matcher=\"" + XMLHelper.escape(excludes[j].getMatcher().getName())
250 + "\"");
220 out.print(listToPrefixedString(ruleConfs, " conf=\""));
221 }
222 out.print(" matcher=\"" + XMLHelper.escape(exclude.getMatcher().getName()) + "\"");
251223 out.println("/>");
252224 }
253225 }
256228 private static void printDependencyExcludeRules(ModuleDescriptor md, PrintWriter out,
257229 ExcludeRule[] excludes) {
258230 if (excludes.length > 0) {
259 for (int j = 0; j < excludes.length; j++) {
260 out.print("\t\t\t<exclude");
261 out.print(" org=\""
262 + XMLHelper.escape(excludes[j].getId().getModuleId().getOrganisation())
263 + "\"");
264 out.print(" module=\""
265 + XMLHelper.escape(excludes[j].getId().getModuleId().getName()) + "\"");
266 out.print(" name=\"" + XMLHelper.escape(excludes[j].getId().getName()) + "\"");
267 out.print(" type=\"" + XMLHelper.escape(excludes[j].getId().getType()) + "\"");
268 out.print(" ext=\"" + XMLHelper.escape(excludes[j].getId().getExt()) + "\"");
269 String[] ruleConfs = excludes[j].getConfigurations();
231 for (ExcludeRule exclude : excludes) {
232 out.print(String.format("\t\t\t<exclude org=\"%s\" module=\"%s\" name=\"%s\" type=\"%s\" ext=\"%s\"",
233 XMLHelper.escape(exclude.getId().getModuleId().getOrganisation()),
234 XMLHelper.escape(exclude.getId().getModuleId().getName()),
235 XMLHelper.escape(exclude.getId().getName()),
236 XMLHelper.escape(exclude.getId().getType()),
237 XMLHelper.escape(exclude.getId().getExt())));
238 String[] ruleConfs = exclude.getConfigurations();
270239 if (!Arrays.asList(ruleConfs).equals(Arrays.asList(md.getConfigurationsNames()))) {
271 out.print(" conf=\"");
272 for (int k = 0; k < ruleConfs.length; k++) {
273 out.print(XMLHelper.escape(ruleConfs[k]));
274 if (k + 1 < ruleConfs.length) {
275 out.print(",");
276 }
277 }
278 out.print("\"");
279 }
280 out.print(" matcher=\"" + XMLHelper.escape(excludes[j].getMatcher().getName())
281 + "\"");
240 out.print(listToPrefixedString(ruleConfs, " conf=\""));
241 }
242 out.print(" matcher=\"" + XMLHelper.escape(exclude.getMatcher().getName()) + "\"");
282243 out.println("/>");
283244 }
284245 }
287248 private static void printDependencyIncludeRules(ModuleDescriptor md, PrintWriter out,
288249 IncludeRule[] includes) {
289250 if (includes.length > 0) {
290 for (int j = 0; j < includes.length; j++) {
291 out.print("\t\t\t<include");
292 out.print(" name=\"" + XMLHelper.escape(includes[j].getId().getName()) + "\"");
293 out.print(" type=\"" + XMLHelper.escape(includes[j].getId().getType()) + "\"");
294 out.print(" ext=\"" + XMLHelper.escape(includes[j].getId().getExt()) + "\"");
295 String[] ruleConfs = includes[j].getConfigurations();
251 for (IncludeRule include : includes) {
252 out.print(String.format("\t\t\t<include name=\"%s\" type=\"%s\" ext=\"%s\"",
253 XMLHelper.escape(include.getId().getName()),
254 XMLHelper.escape(include.getId().getType()),
255 XMLHelper.escape(include.getId().getExt())));
256 String[] ruleConfs = include.getConfigurations();
296257 if (!Arrays.asList(ruleConfs).equals(Arrays.asList(md.getConfigurationsNames()))) {
297 out.print(" conf=\"");
298 for (int k = 0; k < ruleConfs.length; k++) {
299 out.print(XMLHelper.escape(ruleConfs[k]));
300 if (k + 1 < ruleConfs.length) {
301 out.print(",");
302 }
303 }
304 out.print("\"");
305 }
306 out.print(" matcher=\"" + XMLHelper.escape(includes[j].getMatcher().getName())
307 + "\"");
258 out.print(listToPrefixedString(ruleConfs, " conf=\""));
259 }
260 out.print(" matcher=\"" + XMLHelper.escape(include.getMatcher().getName()) + "\"");
308261 out.println("/>");
309262 }
310263 }
313266 private static void printDependencyArtefacts(ModuleDescriptor md, PrintWriter out,
314267 DependencyArtifactDescriptor[] depArtifacts) {
315268 if (depArtifacts.length > 0) {
316 for (int j = 0; j < depArtifacts.length; j++) {
317 out.print("\t\t\t<artifact");
318 out.print(" name=\"" + XMLHelper.escape(depArtifacts[j].getName()) + "\"");
319 out.print(" type=\"" + XMLHelper.escape(depArtifacts[j].getType()) + "\"");
320 out.print(" ext=\"" + XMLHelper.escape(depArtifacts[j].getExt()) + "\"");
321 String[] dadconfs = depArtifacts[j].getConfigurations();
322 if (!Arrays.asList(dadconfs).equals(Arrays.asList(md.getConfigurationsNames()))) {
323 out.print(" conf=\"");
324 for (int k = 0; k < dadconfs.length; k++) {
325 out.print(XMLHelper.escape(dadconfs[k]));
326 if (k + 1 < dadconfs.length) {
327 out.print(",");
328 }
269 for (DependencyArtifactDescriptor depArtifact : depArtifacts) {
270 out.print(String.format("\t\t\t<artifact name=\"%s\" type=\"%s\" ext=\"%s\"",
271 XMLHelper.escape(depArtifact.getName()),
272 XMLHelper.escape(depArtifact.getType()),
273 XMLHelper.escape(depArtifact.getExt())));
274 final String[] dadConfs = depArtifact.getConfigurations();
275 if (dadConfs != null && dadConfs.length > 0) {
276 if (!Arrays.asList(dadConfs).equals(Arrays.asList(md.getConfigurationsNames()))) {
277 out.print(listToPrefixedString(dadConfs, " conf=\""));
329278 }
330 out.print("\"");
331 }
332 printExtraAttributes(depArtifacts[j], out, " ");
333 out.println("/>");
334 }
335 }
279 }
280 printExtraAttributes(depArtifact, out, " ");
281 out.println("/>");
282 }
283 }
284 }
285
286 private static String listToPrefixedString(String[] confs, String prefix) {
287 StringBuilder sb = new StringBuilder(prefix);
288 for (String conf : confs) {
289 if (sb.length() > prefix.length()) {
290 sb.append(",");
291 }
292 sb.append(XMLHelper.escape(conf));
293 }
294 if (prefix.endsWith("\"")) {
295 sb.append("\"");
296 }
297 return sb.toString();
336298 }
337299
338300 /**
339301 * Writes the extra attributes of the given {@link ExtendableItem} to the given
340302 * <tt>PrintWriter</tt>.
341 *
303 *
342304 * @param item
343305 * the {@link ExtendableItem}, cannot be <tt>null</tt>
344306 * @param out
353315 /**
354316 * Writes the specified <tt>Map</tt> containing the extra attributes to the given
355317 * <tt>PrintWriter</tt>.
356 *
318 *
357319 * @param extra
358320 * the extra attributes, can be <tt>null</tt>
359321 * @param out
361323 * @param prefix
362324 * the string to write before writing the attributes (if any)
363325 */
364 private static void printExtraAttributes(Map extra, PrintWriter out, String prefix) {
326 private static void printExtraAttributes(Map<String, String> extra, PrintWriter out, String prefix) {
365327 if (extra == null) {
366328 return;
367329 }
368330
369331 String delim = prefix;
370 for (Iterator iter = extra.entrySet().iterator(); iter.hasNext();) {
371 Map.Entry entry = (Map.Entry) iter.next();
372 out.print(delim + entry.getKey() + "=\""
373 + XMLHelper.escape(entry.getValue().toString()) + "\"");
332 for (Map.Entry<String, String> entry : extra.entrySet()) {
333 out.print(String.format("%s%s=\"%s\"", delim, entry.getKey(),
334 XMLHelper.escape(entry.getValue())));
374335 delim = " ";
375336 }
376337 }
377338
378339 private static void printPublications(ModuleDescriptor md, PrintWriter out) {
379340 out.println("\t<publications>");
380 Artifact[] artifacts = md.getAllArtifacts();
381 for (int i = 0; i < artifacts.length; i++) {
382 out.print("\t\t<artifact");
383 out.print(" name=\"" + XMLHelper.escape(artifacts[i].getName()) + "\"");
384 out.print(" type=\"" + XMLHelper.escape(artifacts[i].getType()) + "\"");
385 out.print(" ext=\"" + XMLHelper.escape(artifacts[i].getExt()) + "\"");
386 out.print(" conf=\"" + XMLHelper.escape(getConfs(md, artifacts[i])) + "\"");
387 printExtraAttributes(artifacts[i], out, " ");
341 for (Artifact artifact : md.getAllArtifacts()) {
342 out.print(String.format("\t\t<artifact name=\"%s\" type=\"%s\" ext=\"%s\" conf=\"%s\"",
343 XMLHelper.escape(artifact.getName()),
344 XMLHelper.escape(artifact.getType()),
345 XMLHelper.escape(artifact.getExt()),
346 XMLHelper.escape(getConfs(md, artifact))));
347 printExtraAttributes(artifact, out, " ");
388348 out.println("/>");
389349 }
390350 out.println("\t</publications>");
394354 Configuration[] confs = md.getConfigurations();
395355 if (confs.length > 0) {
396356 out.println("\t<configurations>");
397 for (int i = 0; i < confs.length; i++) {
398 Configuration conf = confs[i];
357 for (Configuration conf : confs) {
399358 out.print("\t\t");
400359 printConfiguration(conf, out);
401360 }
412371 }
413372 String[] exts = conf.getExtends();
414373 if (exts.length > 0) {
415 out.print(" extends=\"");
416 for (int j = 0; j < exts.length; j++) {
417 out.print(XMLHelper.escape(exts[j]));
418 if (j + 1 < exts.length) {
419 out.print(",");
420 }
421 }
422 out.print("\"");
374 out.print(listToPrefixedString(exts, " extends=\""));
423375 }
424376 if (!conf.isTransitive()) {
425377 out.print(" transitive=\"false\"");
461413 }
462414 if (requireInnerInfoElement(md)) {
463415 out.println("\t>");
464 ExtendsDescriptor[] parents = md.getInheritedDescriptors();
465 for (int i = 0; i < parents.length; i++) {
466 ExtendsDescriptor parent = parents[i];
416 for (ExtendsDescriptor parent : md.getInheritedDescriptors()) {
467417 ModuleRevisionId mrid = parent.getParentRevisionId();
468 out.print("\t\t<extends organisation=\"" + XMLHelper.escape(mrid.getOrganisation())
469 + "\"" + " module=\"" + XMLHelper.escape(mrid.getName()) + "\""
470 + " revision=\"" + XMLHelper.escape(mrid.getRevision()) + "\"");
418 out.print(String.format("\t\t<extends organisation=\"%s\" module=\"%s\" revision=\"%s\"",
419 XMLHelper.escape(mrid.getOrganisation()),
420 XMLHelper.escape(mrid.getName()),
421 XMLHelper.escape(mrid.getRevision())));
471422
472423 String location = parent.getLocation();
473424 if (location != null) {
474425 out.print(" location=\"" + XMLHelper.escape(location) + "\"");
475426 }
476 out.print(" extendType=\"" + StringUtils.join(parent.getExtendsTypes(), ",") + "\"");
427 out.print(" extendType=\"" + joinArray(parent.getExtendsTypes(), ",") + "\"");
477428 out.println("/>");
478429 }
479430 License[] licenses = md.getLicenses();
480 for (int i = 0; i < licenses.length; i++) {
481 License license = licenses[i];
431 for (License license : licenses) {
482432 out.print("\t\t<license ");
483433 if (license.getName() != null) {
484434 out.print("name=\"" + XMLHelper.escape(license.getName()) + "\" ");
493443 if (md.getHomePage() != null) {
494444 out.print(" homepage=\"" + XMLHelper.escape(md.getHomePage()) + "\"");
495445 }
496 if (md.getDescription() != null && md.getDescription().trim().length() > 0) {
446 if (isNullOrEmpty(md.getDescription())) {
447 out.println(" />");
448 } else {
497449 out.println(">");
498450 out.println("\t\t" + XMLHelper.escape(md.getDescription()));
499451 out.println("\t\t</description>");
500 } else {
501 out.println(" />");
502452 }
503453 }
504454 for (ExtraInfoHolder extraInfo : md.getExtraInfos()) {
517467 }
518468 out.print("<");
519469 out.print(extraInfo.getName());
520 for (Entry<String, String> entry : extraInfo.getAttributes().entrySet()) {
521 out.print(" ");
522 out.print(entry.getKey());
523 out.print("=");
524 out.print("\"");
525 out.print(entry.getValue());
526 out.print("\"");
470 for (Map.Entry<String, String> entry : extraInfo.getAttributes().entrySet()) {
471 out.print(String.format(" %s=\"%s\"", entry.getKey(), entry.getValue()));
527472 }
528473 boolean requireClosingTag = false;
529 if (extraInfo.getContent() != null && extraInfo.getContent().trim().length() > 0) {
474 if (!isNullOrEmpty(extraInfo.getContent())) {
530475 out.print(">");
531476 out.print(XMLHelper.escape(extraInfo.getContent()));
532477 requireClosingTag = true;
552497 }
553498
554499 private static boolean requireInnerInfoElement(ModuleDescriptor md) {
555 return md.getExtraInfo().size() > 0 || md.getExtraInfos().size() > 0
556 || md.getHomePage() != null
557 || (md.getDescription() != null && md.getDescription().trim().length() > 0)
500 return md.getExtraInfos().size() > 0 || md.getHomePage() != null
501 || !isNullOrEmpty(md.getDescription())
558502 || md.getLicenses().length > 0 || md.getInheritedDescriptors().length > 0;
559503 }
560504
561505 private static String getConfs(ModuleDescriptor md, Artifact artifact) {
562 StringBuffer ret = new StringBuffer();
563
564 String[] confs = md.getConfigurationsNames();
565 for (int i = 0; i < confs.length; i++) {
566 if (Arrays.asList(md.getArtifacts(confs[i])).contains(artifact)) {
567 ret.append(confs[i]).append(",");
506 StringBuilder ret = new StringBuilder();
507 for (String conf : md.getConfigurationsNames()) {
508 if (Arrays.asList(md.getArtifacts(conf)).contains(artifact)) {
509 ret.append(conf).append(",");
568510 }
569511 }
570512 if (ret.length() > 0) {
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
1919 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
20
21 <xs:complexType name="configurations-conf">
20 <xs:complexType name="configurations-conf">
2221 <xs:attribute name="name" type="xs:string" use="required"/>
2322 <xs:attribute name="transitive" type="xs:boolean"/>
2423 <xs:attribute name="extends" type="xs:string"/>
2524 <xs:attribute name="description" type="xs:string"/>
2625 <xs:attribute name="deprecated" type="xs:string"/>
2726 <xs:attribute name="visibility" default="public">
28 <xs:simpleType>
29 <xs:restriction base="xs:string">
30 <xs:enumeration value="private"/>
31 <xs:enumeration value="public"/>
32 </xs:restriction>
33 </xs:simpleType>
34 </xs:attribute>
35 <xs:anyAttribute namespace="##other" processContents="lax" />
36 </xs:complexType>
37
38 <xs:complexType name="global-exclude">
27 <xs:simpleType>
28 <xs:restriction base="xs:string">
29 <xs:enumeration value="private"/>
30 <xs:enumeration value="public"/>
31 </xs:restriction>
32 </xs:simpleType>
33 </xs:attribute>
34 <xs:anyAttribute namespace="##other" processContents="lax"/>
35 </xs:complexType>
36
37 <xs:complexType name="global-exclude">
3938 <xs:sequence>
40 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
41 <xs:complexType>
42 <xs:attribute name="name" type="xs:string" use="required"/>
43 </xs:complexType>
44 </xs:element>
39 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
40 <xs:complexType>
41 <xs:attribute name="name" type="xs:string" use="required"/>
42 </xs:complexType>
43 </xs:element>
4544 </xs:sequence>
4645 <xs:attribute name="org" type="xs:string"/>
4746 <xs:attribute name="module" type="xs:string"/>
5049 <xs:attribute name="ext" type="xs:string"/>
5150 <xs:attribute name="conf" type="xs:string"/>
5251 <xs:attribute name="matcher" type="xs:string"/>
53 <xs:anyAttribute namespace="##other" processContents="lax" />
54 </xs:complexType>
55
56 <xs:element name="ivy-module">
57 <xs:complexType>
58 <xs:sequence>
59 <xs:element name="info">
60 <xs:complexType>
61 <xs:sequence>
62 <xs:element name="extends" minOccurs="0" maxOccurs="unbounded">
63 <xs:complexType>
64 <xs:attribute name="organisation" type="xs:string" use="required"/>
65 <xs:attribute name="module" type="xs:string" use="required"/>
66 <xs:attribute name="revision" type="xs:string" use="required"/>
67 <xs:attribute name="location" type="xs:string" />
68 <xs:attribute name="extendType" type="xs:string" />
69 </xs:complexType>
70 </xs:element>
71 <xs:element name="license" minOccurs="0" maxOccurs="unbounded">
72 <xs:complexType>
73 <xs:attribute name="name" type="xs:string" use="required"/>
74 <xs:attribute name="url" type="xs:string"/>
75 </xs:complexType>
76 </xs:element>
77 <xs:element name="ivyauthor" minOccurs="0" maxOccurs="unbounded">
78 <xs:complexType>
79 <xs:attribute name="name" type="xs:string" use="required"/>
80 <xs:attribute name="url" type="xs:string"/>
81 </xs:complexType>
82 </xs:element>
83 <xs:element name="repository" minOccurs="0" maxOccurs="unbounded">
84 <xs:complexType>
85 <xs:attribute name="name" type="xs:string" use="required"/>
86 <xs:attribute name="url" type="xs:string"/>
87 <xs:attribute name="pattern" type="xs:string"/>
88 <xs:attribute name="ivys" type="xs:boolean"/>
89 <xs:attribute name="artifacts" type="xs:boolean"/>
90 </xs:complexType>
91 </xs:element>
92 <xs:element name="description" minOccurs="0" maxOccurs="1">
93 <xs:complexType mixed="true">
94 <xs:sequence>
95 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
96 </xs:sequence>
97 <xs:attribute name="homepage" type="xs:string"/>
98 </xs:complexType>
99 </xs:element>
100 <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="lax"/>
101 </xs:sequence>
102 <xs:attribute name="organisation" type="xs:string"/>
103 <xs:attribute name="module" type="xs:string" use="required"/>
104 <xs:attribute name="branch" type="xs:string"/>
105 <xs:attribute name="revision" type="xs:string"/>
106 <xs:attribute name="status" type="xs:string"/>
107 <xs:attribute name="publication" type="xs:string"/>
108 <xs:attribute name="resolver" type="xs:string"/>
109 <xs:attribute name="namespace" type="xs:string"/>
110 <xs:attribute name="default" type="xs:boolean"/>
111 <xs:anyAttribute namespace="##other" processContents="lax" />
112 </xs:complexType>
113 </xs:element>
114 <xs:element name="configurations" minOccurs="0">
115 <xs:complexType>
116 <xs:sequence>
117 <xs:choice minOccurs="0" maxOccurs="unbounded">
118 <xs:element name="conf" type="configurations-conf"/>
119 <xs:element name="include">
120 <xs:complexType>
121 <xs:attribute name="file" type="xs:string"/>
122 <xs:attribute name="url" type="xs:string"/>
123 </xs:complexType>
124 </xs:element>
125 </xs:choice>
126 </xs:sequence>
127 <xs:attribute name="defaultconf" type="xs:string"/>
128 <xs:attribute name="defaultconfmapping" type="xs:string"/>
129 <xs:attribute name="confmappingoverride" type="xs:boolean" />
130 </xs:complexType>
131 </xs:element>
132 <xs:element name="publications" minOccurs="0">
133 <xs:complexType>
134 <xs:sequence>
135 <xs:element name="artifact" minOccurs="0" maxOccurs="unbounded">
136 <xs:complexType>
137 <xs:sequence>
138 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
139 <xs:complexType>
140 <xs:attribute name="name" type="xs:string" use="required"/>
141 </xs:complexType>
142 </xs:element>
143 </xs:sequence>
144 <xs:attribute name="name" type="xs:string"/>
145 <xs:attribute name="type" type="xs:string"/>
146 <xs:attribute name="ext" type="xs:string"/>
147 <xs:attribute name="conf" type="xs:string"/>
148 <xs:attribute name="url" type="xs:string"/>
52 <xs:anyAttribute namespace="##other" processContents="lax"/>
53 </xs:complexType>
54
55 <xs:element name="ivy-module">
56 <xs:complexType>
57 <xs:sequence>
58 <xs:element name="info">
59 <xs:complexType>
60 <xs:sequence>
61 <xs:element name="extends" minOccurs="0" maxOccurs="unbounded">
62 <xs:complexType>
63 <xs:attribute name="organisation" type="xs:string" use="required"/>
64 <xs:attribute name="module" type="xs:string" use="required"/>
65 <xs:attribute name="revision" type="xs:string" use="required"/>
66 <xs:attribute name="location" type="xs:string"/>
67 <xs:attribute name="extendType" type="xs:string"/>
68 </xs:complexType>
69 </xs:element>
70 <xs:element name="license" minOccurs="0" maxOccurs="unbounded">
71 <xs:complexType>
72 <xs:attribute name="name" type="xs:string" use="required"/>
73 <xs:attribute name="url" type="xs:string"/>
74 </xs:complexType>
75 </xs:element>
76 <xs:element name="ivyauthor" minOccurs="0" maxOccurs="unbounded">
77 <xs:complexType>
78 <xs:attribute name="name" type="xs:string" use="required"/>
79 <xs:attribute name="url" type="xs:string"/>
80 </xs:complexType>
81 </xs:element>
82 <xs:element name="repository" minOccurs="0" maxOccurs="unbounded">
83 <xs:complexType>
84 <xs:attribute name="name" type="xs:string" use="required"/>
85 <xs:attribute name="url" type="xs:string"/>
86 <xs:attribute name="pattern" type="xs:string"/>
87 <xs:attribute name="ivys" type="xs:boolean"/>
88 <xs:attribute name="artifacts" type="xs:boolean"/>
89 </xs:complexType>
90 </xs:element>
91 <xs:element name="description" minOccurs="0" maxOccurs="1">
92 <xs:complexType mixed="true">
93 <xs:sequence>
94 <xs:any minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
95 </xs:sequence>
96 <xs:attribute name="homepage" type="xs:string"/>
97 </xs:complexType>
98 </xs:element>
99 <xs:any minOccurs="0" maxOccurs="unbounded" namespace="##other" processContents="lax"/>
100 </xs:sequence>
101 <xs:attribute name="organisation" type="xs:string"/>
102 <xs:attribute name="module" type="xs:string" use="required"/>
103 <xs:attribute name="branch" type="xs:string"/>
104 <xs:attribute name="revision" type="xs:string"/>
105 <xs:attribute name="status" type="xs:string"/>
106 <xs:attribute name="publication" type="xs:string"/>
107 <xs:attribute name="resolver" type="xs:string"/>
108 <xs:attribute name="namespace" type="xs:string"/>
109 <xs:attribute name="default" type="xs:boolean"/>
110 <xs:anyAttribute namespace="##other" processContents="lax"/>
111 </xs:complexType>
112 </xs:element>
113 <xs:element name="configurations" minOccurs="0">
114 <xs:complexType>
115 <xs:sequence>
116 <xs:choice minOccurs="0" maxOccurs="unbounded">
117 <xs:element name="conf" type="configurations-conf"/>
118 <xs:element name="include">
119 <xs:complexType>
120 <xs:attribute name="file" type="xs:string"/>
121 <xs:attribute name="url" type="xs:string"/>
122 </xs:complexType>
123 </xs:element>
124 </xs:choice>
125 </xs:sequence>
126 <xs:attribute name="defaultconf" type="xs:string"/>
127 <xs:attribute name="defaultconfmapping" type="xs:string"/>
128 <xs:attribute name="confmappingoverride" type="xs:boolean"/>
129 </xs:complexType>
130 </xs:element>
131 <xs:element name="publications" minOccurs="0">
132 <xs:complexType>
133 <xs:sequence>
134 <xs:element name="artifact" minOccurs="0" maxOccurs="unbounded">
135 <xs:complexType>
136 <xs:sequence>
137 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
138 <xs:complexType>
139 <xs:attribute name="name" type="xs:string" use="required"/>
140 </xs:complexType>
141 </xs:element>
142 </xs:sequence>
143 <xs:attribute name="name" type="xs:string"/>
144 <xs:attribute name="type" type="xs:string"/>
145 <xs:attribute name="ext" type="xs:string"/>
146 <xs:attribute name="conf" type="xs:string"/>
147 <xs:attribute name="url" type="xs:string"/>
149148 <xs:attribute name="packaging" type="xs:string"/>
150 <xs:anyAttribute namespace="##other" processContents="lax" />
151 </xs:complexType>
152 </xs:element>
153 </xs:sequence>
154 <xs:attribute name="defaultconf" type="xs:string"/>
155 </xs:complexType>
156 </xs:element>
157 <xs:element name="dependencies" minOccurs="0">
158 <xs:complexType>
159 <xs:sequence>
160 <xs:element name="dependency" minOccurs="0" maxOccurs="unbounded">
161 <xs:complexType>
162 <xs:sequence>
163 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
164 <xs:complexType>
165 <xs:sequence>
166 <xs:element name="mapped" minOccurs="0" maxOccurs="unbounded">
167 <xs:complexType>
168 <xs:attribute name="name" type="xs:string" use="required"/>
169 </xs:complexType>
170 </xs:element>
171 </xs:sequence>
172 <xs:attribute name="name" type="xs:string" use="required"/>
173 <xs:attribute name="mapped" type="xs:string"/>
174 </xs:complexType>
175 </xs:element>
176 <xs:element name="artifact" minOccurs="0" maxOccurs="unbounded">
177 <xs:complexType>
178 <xs:sequence>
179 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
180 <xs:complexType>
181 <xs:attribute name="name" type="xs:string" use="required"/>
182 </xs:complexType>
183 </xs:element>
184 </xs:sequence>
185 <xs:attribute name="name" type="xs:string" use="required"/>
186 <xs:attribute name="type" type="xs:string"/>
187 <xs:attribute name="ext" type="xs:string"/>
188 <xs:attribute name="conf" type="xs:string"/>
189 <xs:attribute name="url" type="xs:string"/>
190 <xs:anyAttribute namespace="##other" processContents="lax" />
191 </xs:complexType>
192 </xs:element>
193 <xs:element name="include" minOccurs="0" maxOccurs="unbounded">
194 <xs:complexType>
195 <xs:sequence>
196 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
197 <xs:complexType>
198 <xs:attribute name="name" type="xs:string" use="required"/>
199 </xs:complexType>
200 </xs:element>
201 </xs:sequence>
202 <xs:attribute name="name" type="xs:string"/>
203 <xs:attribute name="type" type="xs:string"/>
204 <xs:attribute name="ext" type="xs:string"/>
205 <xs:attribute name="conf" type="xs:string"/>
206 <xs:attribute name="matcher" type="xs:string"/>
207 <xs:anyAttribute namespace="##other" processContents="lax" />
208 </xs:complexType>
209 </xs:element>
210 <xs:element name="exclude" minOccurs="0" maxOccurs="unbounded">
211 <xs:complexType>
212 <xs:sequence>
213 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
214 <xs:complexType>
215 <xs:attribute name="name" type="xs:string" use="required"/>
216 </xs:complexType>
217 </xs:element>
218 </xs:sequence>
219 <xs:attribute name="org" type="xs:string"/>
220 <xs:attribute name="module" type="xs:string"/>
221 <xs:attribute name="name" type="xs:string"/>
222 <xs:attribute name="type" type="xs:string"/>
223 <xs:attribute name="ext" type="xs:string"/>
224 <xs:attribute name="conf" type="xs:string"/>
225 <xs:attribute name="matcher" type="xs:string"/>
226 <xs:anyAttribute namespace="##other" processContents="lax" />
227 </xs:complexType>
228 </xs:element>
229 </xs:sequence>
230 <xs:attribute name="org" type="xs:string"/>
231 <xs:attribute name="name" type="xs:string" use="required"/>
232 <xs:attribute name="branch" type="xs:string"/>
233 <xs:attribute name="branchConstraint" type="xs:string"/>
234 <xs:attribute name="rev" type="xs:string" use="required"/>
235 <xs:attribute name="revConstraint" type="xs:string"/>
236 <xs:attribute name="force" type="xs:boolean"/>
237 <xs:attribute name="changing" type="xs:boolean" default="false"/>
238 <xs:attribute name="transitive" type="xs:boolean" default="true"/>
239 <xs:attribute name="conf" type="xs:string"/>
240 <xs:anyAttribute namespace="##other" processContents="lax" />
241 </xs:complexType>
242 </xs:element>
243 <xs:element name="exclude" type="global-exclude" minOccurs="0" maxOccurs="unbounded" />
244 <xs:element name="override" minOccurs="0" maxOccurs="unbounded">
245 <xs:complexType>
246 <xs:attribute name="org" type="xs:string"/>
247 <xs:attribute name="module" type="xs:string"/>
248 <xs:attribute name="matcher" type="xs:string"/>
249 <xs:attribute name="rev" type="xs:string"/>
250 <xs:attribute name="branch" type="xs:string"/>
251 </xs:complexType>
252 </xs:element>
253 <xs:element name="conflict" minOccurs="0" maxOccurs="unbounded">
254 <xs:complexType>
255 <xs:attribute name="org" type="xs:string"/>
256 <xs:attribute name="module" type="xs:string"/>
257 <xs:attribute name="manager" type="xs:string"/>
258 <xs:attribute name="rev" type="xs:string"/>
259 <xs:attribute name="matcher" type="xs:string"/>
260 <xs:anyAttribute namespace="##other" processContents="lax" />
261 </xs:complexType>
262 </xs:element>
263 </xs:sequence>
264 <xs:attribute name="defaultconf" type="xs:string"/>
265 <xs:attribute name="defaultconfmapping" type="xs:string"/>
266 <xs:attribute name="confmappingoverride" type="xs:boolean" />
267 </xs:complexType>
268 </xs:element>
269 <xs:element name="conflicts" minOccurs="0">
270 <xs:complexType>
271 <xs:sequence>
272 <xs:element name="manager" maxOccurs="unbounded">
273 <xs:complexType>
274 <xs:attribute name="org" type="xs:string"/>
275 <xs:attribute name="module" type="xs:string"/>
276 <xs:attribute name="name" type="xs:string"/>
277 <xs:attribute name="rev" type="xs:string"/>
278 <xs:attribute name="matcher" type="xs:string"/>
279 <xs:anyAttribute namespace="##other" processContents="lax" />
280 </xs:complexType>
281 </xs:element>
282 </xs:sequence>
283 </xs:complexType>
284 </xs:element>
285 </xs:sequence>
286 <xs:attribute name="version" type="xs:string" use="required"/>
287 </xs:complexType>
288 </xs:element>
289
149 <xs:anyAttribute namespace="##other" processContents="lax"/>
150 </xs:complexType>
151 </xs:element>
152 </xs:sequence>
153 <xs:attribute name="defaultconf" type="xs:string"/>
154 </xs:complexType>
155 </xs:element>
156 <xs:element name="dependencies" minOccurs="0">
157 <xs:complexType>
158 <xs:sequence>
159 <xs:element name="dependency" minOccurs="0" maxOccurs="unbounded">
160 <xs:complexType>
161 <xs:sequence>
162 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
163 <xs:complexType>
164 <xs:sequence>
165 <xs:element name="mapped" minOccurs="0" maxOccurs="unbounded">
166 <xs:complexType>
167 <xs:attribute name="name" type="xs:string" use="required"/>
168 </xs:complexType>
169 </xs:element>
170 </xs:sequence>
171 <xs:attribute name="name" type="xs:string" use="required"/>
172 <xs:attribute name="mapped" type="xs:string"/>
173 </xs:complexType>
174 </xs:element>
175 <xs:element name="artifact" minOccurs="0" maxOccurs="unbounded">
176 <xs:complexType>
177 <xs:sequence>
178 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
179 <xs:complexType>
180 <xs:attribute name="name" type="xs:string" use="required"/>
181 </xs:complexType>
182 </xs:element>
183 </xs:sequence>
184 <xs:attribute name="name" type="xs:string" use="required"/>
185 <xs:attribute name="type" type="xs:string"/>
186 <xs:attribute name="ext" type="xs:string"/>
187 <xs:attribute name="conf" type="xs:string"/>
188 <xs:attribute name="url" type="xs:string"/>
189 <xs:anyAttribute namespace="##other" processContents="lax"/>
190 </xs:complexType>
191 </xs:element>
192 <xs:element name="include" minOccurs="0" maxOccurs="unbounded">
193 <xs:complexType>
194 <xs:sequence>
195 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
196 <xs:complexType>
197 <xs:attribute name="name" type="xs:string" use="required"/>
198 </xs:complexType>
199 </xs:element>
200 </xs:sequence>
201 <xs:attribute name="name" type="xs:string"/>
202 <xs:attribute name="type" type="xs:string"/>
203 <xs:attribute name="ext" type="xs:string"/>
204 <xs:attribute name="conf" type="xs:string"/>
205 <xs:attribute name="matcher" type="xs:string"/>
206 <xs:anyAttribute namespace="##other" processContents="lax"/>
207 </xs:complexType>
208 </xs:element>
209 <xs:element name="exclude" minOccurs="0" maxOccurs="unbounded">
210 <xs:complexType>
211 <xs:sequence>
212 <xs:element name="conf" minOccurs="0" maxOccurs="unbounded">
213 <xs:complexType>
214 <xs:attribute name="name" type="xs:string" use="required"/>
215 </xs:complexType>
216 </xs:element>
217 </xs:sequence>
218 <xs:attribute name="org" type="xs:string"/>
219 <xs:attribute name="module" type="xs:string"/>
220 <xs:attribute name="name" type="xs:string"/>
221 <xs:attribute name="type" type="xs:string"/>
222 <xs:attribute name="ext" type="xs:string"/>
223 <xs:attribute name="conf" type="xs:string"/>
224 <xs:attribute name="matcher" type="xs:string"/>
225 <xs:anyAttribute namespace="##other" processContents="lax"/>
226 </xs:complexType>
227 </xs:element>
228 </xs:sequence>
229 <xs:attribute name="org" type="xs:string"/>
230 <xs:attribute name="name" type="xs:string" use="required"/>
231 <xs:attribute name="branch" type="xs:string"/>
232 <xs:attribute name="branchConstraint" type="xs:string"/>
233 <xs:attribute name="rev" type="xs:string" use="required"/>
234 <xs:attribute name="revConstraint" type="xs:string"/>
235 <xs:attribute name="force" type="xs:boolean"/>
236 <xs:attribute name="changing" type="xs:boolean" default="false"/>
237 <xs:attribute name="transitive" type="xs:boolean" default="true"/>
238 <xs:attribute name="conf" type="xs:string"/>
239 <xs:anyAttribute namespace="##other" processContents="lax"/>
240 </xs:complexType>
241 </xs:element>
242 <xs:element name="exclude" type="global-exclude" minOccurs="0" maxOccurs="unbounded"/>
243 <xs:element name="override" minOccurs="0" maxOccurs="unbounded">
244 <xs:complexType>
245 <xs:attribute name="org" type="xs:string"/>
246 <xs:attribute name="module" type="xs:string"/>
247 <xs:attribute name="matcher" type="xs:string"/>
248 <xs:attribute name="rev" type="xs:string"/>
249 <xs:attribute name="branch" type="xs:string"/>
250 </xs:complexType>
251 </xs:element>
252 <xs:element name="conflict" minOccurs="0" maxOccurs="unbounded">
253 <xs:complexType>
254 <xs:attribute name="org" type="xs:string"/>
255 <xs:attribute name="module" type="xs:string"/>
256 <xs:attribute name="manager" type="xs:string"/>
257 <xs:attribute name="rev" type="xs:string"/>
258 <xs:attribute name="matcher" type="xs:string"/>
259 <xs:anyAttribute namespace="##other" processContents="lax"/>
260 </xs:complexType>
261 </xs:element>
262 </xs:sequence>
263 <xs:attribute name="defaultconf" type="xs:string"/>
264 <xs:attribute name="defaultconfmapping" type="xs:string"/>
265 <xs:attribute name="confmappingoverride" type="xs:boolean"/>
266 </xs:complexType>
267 </xs:element>
268 <xs:element name="conflicts" minOccurs="0">
269 <xs:complexType>
270 <xs:sequence>
271 <xs:element name="manager" maxOccurs="unbounded">
272 <xs:complexType>
273 <xs:attribute name="org" type="xs:string"/>
274 <xs:attribute name="module" type="xs:string"/>
275 <xs:attribute name="name" type="xs:string"/>
276 <xs:attribute name="rev" type="xs:string"/>
277 <xs:attribute name="matcher" type="xs:string"/>
278 <xs:anyAttribute namespace="##other" processContents="lax"/>
279 </xs:complexType>
280 </xs:element>
281 </xs:sequence>
282 </xs:complexType>
283 </xs:element>
284 </xs:sequence>
285 <xs:attribute name="version" type="xs:string" use="required"/>
286 </xs:complexType>
287 </xs:element>
290288 </xs:schema>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4949
5050 if (settings.logModulesInUse() && ResolveOptions.LOG_DEFAULT.equals(options.getLog())) {
5151 Message.info("\t:: modules in use:");
52 List dependencies = new ArrayList(report.getDependencies());
52 List<IvyNode> dependencies = new ArrayList<>(report.getDependencies());
5353 Collections.sort(dependencies);
5454 if (dependencies.size() > 0) {
5555 String[] confs = report.getConfigurations();
56 for (int i = 0; i < dependencies.size(); i++) {
57 IvyNode node = (IvyNode) dependencies.get(i);
56 for (IvyNode node : dependencies) {
5857 if (node.isCompletelyEvicted() || node.hasProblem()) {
5958 continue;
6059 }
61 List nodeConfs = new ArrayList(confs.length);
62 for (int j = 0; j < confs.length; j++) {
63 String conf = confs[j];
60 List<String> nodeConfs = new ArrayList<>(confs.length);
61 for (String conf : confs) {
6462 if (report.getConfigurationReport(conf).getModuleRevisionIds()
6563 .contains(node.getResolvedId())) {
6664 nodeConfs.add(conf);
7674
7775 if (evicted.length > 0 && ResolveOptions.LOG_DEFAULT.equals(options.getLog())) {
7876 Message.info("\t:: evicted modules:");
79 for (int i = 0; i < evicted.length; i++) {
80 Collection allEvictingNodes = evicted[i].getAllEvictingNodesDetails();
77 for (IvyNode evictedNode : evicted) {
78 Collection<String> allEvictingNodes = evictedNode.getAllEvictingNodesDetails();
8179 if (allEvictingNodes == null) {
82 Message.info("\t" + evicted[i] + " transitively in "
83 + Arrays.asList(evicted[i].getEvictedConfs()));
80 Message.info("\t" + evictedNode + " transitively in "
81 + Arrays.asList(evictedNode.getEvictedConfs()));
8482 } else if (allEvictingNodes.isEmpty()) {
85 Message.info("\t" + evicted[i] + " by [] ("
86 + evicted[i].getAllEvictingConflictManagers() + ") in "
87 + Arrays.asList(evicted[i].getEvictedConfs()));
83 Message.info(
84 "\t" + evictedNode + " by [] (" + evictedNode.getAllEvictingConflictManagers()
85 + ") in " + Arrays.asList(evictedNode.getEvictedConfs()));
8886 } else {
89 Message.info("\t" + evicted[i] + " by " + allEvictingNodes + " in "
90 + Arrays.asList(evicted[i].getEvictedConfs()));
87 Message.info("\t" + evictedNode + " by " + allEvictingNodes + " in "
88 + Arrays.asList(evictedNode.getEvictedConfs()));
9189 }
92 String[] confs = evicted[i].getEvictedConfs();
93 for (int j = 0; j < confs.length; j++) {
94 EvictionData evictedData = evicted[i].getEvictedData(confs[j]);
90 for (String conf : evictedNode.getEvictedConfs()) {
91 EvictionData evictedData = evictedNode.getEvictedData(conf);
9592 if (evictedData.getParent() != null) {
9693 Message.verbose("\t in " + evictedData.getParent() + " with "
9794 + evictedData.getConflictManager());
105102 char[] sep = new char[69];
106103 Arrays.fill(sep, '-');
107104 Message.rawinfo("\t" + new String(sep));
108 StringBuffer line = new StringBuffer("\t");
105 StringBuilder line = new StringBuilder("\t");
109106 append(line, "", 18);
110107 append(line, "modules", 31);
111108 line.append("|");
113110 line.append("|");
114111 Message.rawinfo(line.toString());
115112
116 line = new StringBuffer("\t");
113 line = new StringBuilder("\t");
117114 append(line, "conf", 18);
118115 append(line, "number", 7);
119116 append(line, "search", 7);
127124 Message.rawinfo(line.toString());
128125 Message.rawinfo("\t" + new String(sep));
129126
130 String[] confs = report.getConfigurations();
131 for (int i = 0; i < confs.length; i++) {
132 output(report.getConfigurationReport(confs[i]));
127 for (String conf : report.getConfigurations()) {
128 output(report.getConfigurationReport(conf));
133129 }
134130 Message.rawinfo("\t" + new String(sep));
135131 }
140136 Message.warn("\t:: UNRESOLVED DEPENDENCIES ::");
141137 Message.warn("\t::::::::::::::::::::::::::::::::::::::::::::::");
142138 }
143 for (int i = 0; i < unresolved.length; i++) {
144 Message.warn("\t:: " + unresolved[i] + ": " + unresolved[i].getProblemMessage());
139 for (IvyNode anUnresolved : unresolved) {
140 Message.warn("\t:: " + anUnresolved + ": " + anUnresolved.getProblemMessage());
145141 }
146142 if (unresolved.length > 0) {
147143 Message.warn("\t::::::::::::::::::::::::::::::::::::::::::::::\n");
154150 Message.warn("\t:: ^ see resolution messages for details ^ ::");
155151 Message.warn("\t::::::::::::::::::::::::::::::::::::::::::::::");
156152 }
157 for (int i = 0; i < errors.length; i++) {
158 Message.warn("\t:: " + errors[i].getArtifact());
153 for (ArtifactDownloadReport error : errors) {
154 Message.warn("\t:: " + error.getArtifact());
159155 }
160156 if (errors.length > 0) {
161157 Message.warn("\t::::::::::::::::::::::::::::::::::::::::::::::\n");
163159 }
164160
165161 public void output(ConfigurationResolveReport report) {
166 StringBuffer line = new StringBuffer("\t");
162 StringBuilder line = new StringBuilder("\t");
167163 // CheckStyle:MagicNumber| OFF
168164 append(line, report.getConfiguration(), 18);
169165 append(line, String.valueOf(report.getNodesNumber()), 7);
179175 Message.rawinfo(line.toString());
180176 }
181177
182 private void append(StringBuffer line, Object o, int limit) {
178 private void append(StringBuilder line, Object o, int limit) {
183179 String v = String.valueOf(o);
184180 if (v.length() >= limit) {
185181 v = v.substring(0, limit);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 *
2727 */
2828 public interface ReportOutputter {
29 public static final String CONSOLE = "console";
29 String CONSOLE = "console";
3030
31 public static final String XML = "xml";
31 String XML = "xml";
3232
33 public abstract void output(ResolveReport report, ResolutionCacheManager cacheMgr,
33 void output(ResolveReport report, ResolutionCacheManager cacheMgr,
3434 ResolveOptions options) throws IOException;
3535
36 public abstract String getName();
36 String getName();
3737 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4242 public void output(ResolveReport report, ResolutionCacheManager cacheMgr, ResolveOptions options)
4343 throws IOException {
4444 String[] confs = report.getConfigurations();
45 for (int i = 0; i < confs.length; i++) {
46 output(report.getConfigurationReport(confs[i]), report.getResolveId(), confs, cacheMgr);
45 for (String conf : confs) {
46 output(report.getConfigurationReport(conf), report.getResolveId(), confs, cacheMgr);
4747 }
4848 }
4949
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6464 private boolean isDefault;
6565
6666 // Use a TreeMap to order by
67 private SortedMap<Integer, List<ArtifactDownloadReport>> revisionsMap = new TreeMap<Integer, List<ArtifactDownloadReport>>();
67 private SortedMap<Integer, List<ArtifactDownloadReport>> revisionsMap = new TreeMap<>();
6868
6969 private List<ArtifactDownloadReport> revisionArtifacts = null;
7070
7171 public void startElement(String uri, String localName, String qName,
7272 Attributes attributes) throws SAXException {
73 if ("module".equals(qName)) {
74 organisation = attributes.getValue("organisation");
75 module = attributes.getValue("name");
76 } else if ("revision".equals(qName)) {
77 revisionArtifacts = new ArrayList<ArtifactDownloadReport>();
78 branch = attributes.getValue("branch");
79 revision = attributes.getValue("name");
80 isDefault = Boolean.valueOf(attributes.getValue("default")).booleanValue();
81 // retrieve position from file. If no position is found, it may be an old
82 // report generated with a previous version,
83 // in which case, we put it at the last position
84 String pos = attributes.getValue("position");
85 position = pos == null ? getMaxPos() + 1 : Integer.valueOf(pos).intValue();
86 if (attributes.getValue("error") != null) {
87 hasError = true;
88 skip = true;
89 } else if (attributes.getValue("evicted") != null) {
90 skip = true;
91 } else {
92 revisionsMap.put(new Integer(position), revisionArtifacts);
93 mrid = ModuleRevisionId.newInstance(organisation, module, branch, revision,
73 switch (qName) {
74 case "module":
75 organisation = attributes.getValue("organisation");
76 module = attributes.getValue("name");
77 break;
78 case "revision":
79 revisionArtifacts = new ArrayList<>();
80 branch = attributes.getValue("branch");
81 revision = attributes.getValue("name");
82 isDefault = Boolean.valueOf(attributes.getValue("default"));
83 // retrieve position from file. If no position is found, it may be an old
84 // report generated with a previous version,
85 // in which case, we put it at the last position
86 String pos = attributes.getValue("position");
87 position = pos == null ? getMaxPos() + 1 : Integer.valueOf(pos);
88 if (attributes.getValue("error") != null) {
89 hasError = true;
90 skip = true;
91 } else if (attributes.getValue("evicted") != null) {
92 skip = true;
93 } else {
94 revisionsMap.put(position, revisionArtifacts);
95 mrid = ModuleRevisionId.newInstance(organisation, module, branch, revision,
96 ExtendableItemHelper.getExtraAttributes(attributes, "extra-"));
97 mrids.add(mrid);
98 if (isDefault) {
99 defaultMrids.add(mrid);
100 } else {
101 Artifact metadataArtifact = DefaultArtifact.newIvyArtifact(mrid,
102 pubdate);
103 MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(
104 metadataArtifact);
105 metadataReports.put(mrid, madr);
106 realMrids.add(mrid);
107 }
108 try {
109 String pubDateAttr = attributes.getValue("pubdate");
110 if (pubDateAttr != null) {
111 pubdate = DateUtil.parse(pubDateAttr);
112 }
113 skip = false;
114 } catch (ParseException e) {
115 throw new IllegalArgumentException("invalid publication date for "
116 + organisation + " " + module + " " + revision + ": "
117 + attributes.getValue("pubdate"));
118 }
119 }
120 break;
121 case "metadata-artifact":
122 if (skip) {
123 return;
124 }
125 MetadataArtifactDownloadReport madr = metadataReports.get(mrid);
126 if (madr != null) {
127 madr.setDownloadStatus(DownloadStatus.fromString(attributes
128 .getValue("status")));
129 madr.setDownloadDetails(attributes.getValue("details"));
130 madr.setSize(Long.parseLong(attributes.getValue("size")));
131 madr.setDownloadTimeMillis(Long.parseLong(attributes.getValue("time")));
132 madr.setSearched(parseBoolean(attributes.getValue("searched")));
133 if (attributes.getValue("location") != null) {
134 madr.setLocalFile(new File(attributes.getValue("location")));
135 }
136 if (attributes.getValue("original-local-location") != null) {
137 madr.setOriginalLocalFile(new File(attributes
138 .getValue("original-local-location")));
139 }
140 if (attributes.getValue("origin-location") != null) {
141 if (ArtifactOrigin.isUnknown(attributes.getValue("origin-location"))) {
142 madr.setArtifactOrigin(ArtifactOrigin.unknown(madr.getArtifact()));
143 } else {
144 madr.setArtifactOrigin(new ArtifactOrigin(madr.getArtifact(),
145 parseBoolean(attributes.getValue("origin-is-local")),
146 attributes.getValue("origin-location")));
147 }
148 }
149 }
150 break;
151 case "artifact":
152 if (skip) {
153 return;
154 }
155 String status = attributes.getValue("status");
156 String artifactName = attributes.getValue("name");
157 String type = attributes.getValue("type");
158 String ext = attributes.getValue("ext");
159 Artifact artifact = new DefaultArtifact(mrid, pubdate, artifactName, type, ext,
160 ExtendableItemHelper.getExtraAttributes(attributes, "extra-"));
161 ArtifactDownloadReport aReport = new ArtifactDownloadReport(artifact);
162 aReport.setDownloadStatus(DownloadStatus.fromString(status));
163 aReport.setDownloadDetails(attributes.getValue("details"));
164 aReport.setSize(Long.parseLong(attributes.getValue("size")));
165 aReport.setDownloadTimeMillis(Long.parseLong(attributes.getValue("time")));
166 if (attributes.getValue("location") != null) {
167 aReport.setLocalFile(new File(attributes.getValue("location")));
168 }
169 if (attributes.getValue("unpackedFile") != null) {
170 aReport.setUnpackedLocalFile(new File(attributes.getValue("unpackedFile")));
171 }
172 revisionArtifacts.add(aReport);
173 break;
174 case "origin-location":
175 if (skip) {
176 return;
177 }
178 ArtifactDownloadReport adr = revisionArtifacts
179 .get(revisionArtifacts.size() - 1);
180
181 if (ArtifactOrigin.isUnknown(attributes.getValue("location"))) {
182 adr.setArtifactOrigin(ArtifactOrigin.unknown(adr.getArtifact()));
183 } else {
184 adr.setArtifactOrigin(new ArtifactOrigin(adr.getArtifact(),
185 parseBoolean(attributes.getValue("is-local")),
186 attributes.getValue("location")));
187 }
188 break;
189 case "info":
190 String organisation = attributes.getValue("organisation");
191 String name = attributes.getValue("module");
192 String branch = attributes.getValue("branch");
193 String revision = attributes.getValue("revision");
194 mRevisionId = ModuleRevisionId.newInstance(organisation, name, branch, revision,
94195 ExtendableItemHelper.getExtraAttributes(attributes, "extra-"));
95 mrids.add(mrid);
96 if (isDefault) {
97 defaultMrids.add(mrid);
98 } else {
99 Artifact metadataArtifact = DefaultArtifact.newIvyArtifact(mrid,
100 pubdate);
101 MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(
102 metadataArtifact);
103 metadataReports.put(mrid, madr);
104 realMrids.add(mrid);
105 }
106 try {
107 String pubDateAttr = attributes.getValue("pubdate");
108 if (pubDateAttr != null) {
109 pubdate = DateUtil.parse(pubDateAttr);
110 }
111 skip = false;
112 } catch (ParseException e) {
113 throw new IllegalArgumentException("invalid publication date for "
114 + organisation + " " + module + " " + revision + ": "
115 + attributes.getValue("pubdate"));
116 }
117 }
118 } else if ("metadata-artifact".equals(qName)) {
119 if (skip) {
120 return;
121 }
122 MetadataArtifactDownloadReport madr = metadataReports.get(mrid);
123 if (madr != null) {
124 madr.setDownloadStatus(DownloadStatus.fromString(attributes
125 .getValue("status")));
126 madr.setDownloadDetails(attributes.getValue("details"));
127 madr.setSize(Long.parseLong(attributes.getValue("size")));
128 madr.setDownloadTimeMillis(Long.parseLong(attributes.getValue("time")));
129 madr.setSearched(parseBoolean(attributes.getValue("searched")));
130 if (attributes.getValue("location") != null) {
131 madr.setLocalFile(new File(attributes.getValue("location")));
132 }
133 if (attributes.getValue("original-local-location") != null) {
134 madr.setOriginalLocalFile(new File(attributes
135 .getValue("original-local-location")));
136 }
137 if (attributes.getValue("origin-location") != null) {
138 if (ArtifactOrigin.isUnknown(attributes.getValue("origin-location"))) {
139 madr.setArtifactOrigin(ArtifactOrigin.unkwnown(madr.getArtifact()));
140 } else {
141 madr.setArtifactOrigin(new ArtifactOrigin(madr.getArtifact(),
142 parseBoolean(attributes.getValue("origin-is-local")),
143 attributes.getValue("origin-location")));
144 }
145 }
146 }
147 } else if ("artifact".equals(qName)) {
148 if (skip) {
149 return;
150 }
151 String status = attributes.getValue("status");
152 String artifactName = attributes.getValue("name");
153 String type = attributes.getValue("type");
154 String ext = attributes.getValue("ext");
155 Artifact artifact = new DefaultArtifact(mrid, pubdate, artifactName, type, ext,
156 ExtendableItemHelper.getExtraAttributes(attributes, "extra-"));
157 ArtifactDownloadReport aReport = new ArtifactDownloadReport(artifact);
158 aReport.setDownloadStatus(DownloadStatus.fromString(status));
159 aReport.setDownloadDetails(attributes.getValue("details"));
160 aReport.setSize(Long.parseLong(attributes.getValue("size")));
161 aReport.setDownloadTimeMillis(Long.parseLong(attributes.getValue("time")));
162 if (attributes.getValue("location") != null) {
163 aReport.setLocalFile(new File(attributes.getValue("location")));
164 }
165 if (attributes.getValue("unpackedFile") != null) {
166 aReport.setUnpackedLocalFile(new File(attributes.getValue("unpackedFile")));
167 }
168 revisionArtifacts.add(aReport);
169 } else if ("origin-location".equals(qName)) {
170 if (skip) {
171 return;
172 }
173 ArtifactDownloadReport aReport = revisionArtifacts
174 .get(revisionArtifacts.size() - 1);
175
176 if (ArtifactOrigin.isUnknown(attributes.getValue("location"))) {
177 aReport.setArtifactOrigin(ArtifactOrigin.unkwnown(aReport.getArtifact()));
178 } else {
179 aReport.setArtifactOrigin(new ArtifactOrigin(aReport.getArtifact(),
180 parseBoolean(attributes.getValue("is-local")), attributes
181 .getValue("location")));
182 }
183 } else if ("info".equals(qName)) {
184 String organisation = attributes.getValue("organisation");
185 String name = attributes.getValue("module");
186 String branch = attributes.getValue("branch");
187 String revision = attributes.getValue("revision");
188 Map<String, String> extraAttributes = new HashMap<String, String>();
189 for (int i = 0; i < attributes.getLength(); i++) {
190 String attName = attributes.getQName(i);
191 if (attName.startsWith("extra-")) {
192 String extraAttrName = attName.substring("extra-".length());
193 String extraAttrValue = attributes.getValue(i);
194 extraAttributes.put(extraAttrName, extraAttrValue);
195 }
196 }
197 mRevisionId = ModuleRevisionId.newInstance(organisation, name, branch,
198 revision, extraAttributes);
196 break;
199197 }
200198 }
201199
216214
217215 private int getMaxPos() {
218216 return revisionsMap.isEmpty() ? -1
219 : ((Integer) revisionsMap.keySet().toArray()[revisionsMap.size() - 1])
220 .intValue();
217 : (Integer) revisionsMap.keySet().toArray()[revisionsMap.size() - 1];
221218 }
222219 }
223220
224 private List<ModuleRevisionId> mrids = new ArrayList<ModuleRevisionId>();
225
226 private List<ModuleRevisionId> defaultMrids = new ArrayList<ModuleRevisionId>();
227
228 private List<ModuleRevisionId> realMrids = new ArrayList<ModuleRevisionId>();
229
230 private List<Artifact> artifacts = new ArrayList<Artifact>();
231
232 private List<ArtifactDownloadReport> artifactReports = new ArrayList<ArtifactDownloadReport>();
233
234 private Map<ModuleRevisionId, MetadataArtifactDownloadReport> metadataReports = new HashMap<ModuleRevisionId, MetadataArtifactDownloadReport>();
221 private List<ModuleRevisionId> mrids = new ArrayList<>();
222
223 private List<ModuleRevisionId> defaultMrids = new ArrayList<>();
224
225 private List<ModuleRevisionId> realMrids = new ArrayList<>();
226
227 private List<Artifact> artifacts = new ArrayList<>();
228
229 private List<ArtifactDownloadReport> artifactReports = new ArrayList<>();
230
231 private Map<ModuleRevisionId, MetadataArtifactDownloadReport> metadataReports = new HashMap<>();
235232
236233 private ModuleRevisionId mRevisionId;
237234
321318
322319 /**
323320 * Returns the <tt>ModuleRevisionId</tt> of the resolved module.
321 *
322 * @return ModuleRevisionId
324323 */
325324 public ModuleRevisionId getResolvedModule() {
326325 return parser.getResolvedModule();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.util.ArrayList;
2525 import java.util.Collection;
2626 import java.util.Date;
27 import java.util.Iterator;
2827 import java.util.List;
2928 import java.util.Map;
30 import java.util.Map.Entry;
3129
3230 import org.apache.ivy.core.cache.ArtifactOrigin;
31 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
3332 import org.apache.ivy.core.module.descriptor.License;
3433 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
3534 import org.apache.ivy.core.module.id.ModuleId;
4140 import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
4241 import org.apache.ivy.core.resolve.IvyNodeEviction.EvictionData;
4342 import org.apache.ivy.util.DateUtil;
44 import org.apache.ivy.util.StringUtils;
4543 import org.apache.ivy.util.XMLHelper;
44 import org.apache.ivy.util.extendable.ExtendableItemHelper;
45
46 import static org.apache.ivy.util.StringUtils.joinArray;
4647
4748 /**
4849 * XmlReportWriter allows to write ResolveReport in an xml format.
5051 public class XmlReportWriter {
5152
5253 static final String REPORT_ENCODING = "UTF-8";
54 private static final String SEPARATOR = " ";
5355
5456 public void output(ConfigurationResolveReport report, OutputStream stream) {
5557 output(report, new String[] {report.getConfiguration()}, stream);
7577 if (mrid.getBranch() != null) {
7678 out.println("\t\tbranch=\"" + XMLHelper.escape(mrid.getBranch()) + "\"");
7779 }
78 Map extraAttributes = mrid.getExtraAttributes();
79 for (Iterator it = extraAttributes.entrySet().iterator(); it.hasNext();) {
80 Map.Entry entry = (Entry) it.next();
81 out.println("\t\textra-" + entry.getKey() + "=\""
82 + XMLHelper.escape(entry.getValue().toString()) + "\"");
83 }
80 out.println(extraToString(mrid.getQualifiedExtraAttributes(), "\t\t"));
8481 out.println("\t\tconf=\"" + XMLHelper.escape(report.getConfiguration()) + "\"");
85 out.println("\t\tconfs=\"" + XMLHelper.escape(StringUtils.join(confs, ", ")) + "\"");
82 out.println("\t\tconfs=\"" + XMLHelper.escape(joinArray(confs, ", ")) + "\"");
8683 out.println("\t\tdate=\"" + DateUtil.format(report.getDate()) + "\"/>");
8784
8885 out.println("\t<dependencies>");
8986
9087 // create a list of ModuleRevisionIds indicating the position for each dependency
91 List dependencies = new ArrayList(report.getModuleRevisionIds());
92
93 for (Iterator iter = report.getModuleIds().iterator(); iter.hasNext();) {
94 ModuleId mid = (ModuleId) iter.next();
88 List<ModuleRevisionId> dependencies = new ArrayList<>(report.getModuleRevisionIds());
89
90 for (ModuleId mid : report.getModuleIds()) {
9591 out.println("\t\t<module organisation=\"" + XMLHelper.escape(mid.getOrganisation())
9692 + "\"" + " name=\"" + XMLHelper.escape(mid.getName()) + "\">");
97 for (Iterator it2 = report.getNodes(mid).iterator(); it2.hasNext();) {
98 IvyNode dep = (IvyNode) it2.next();
99 ouputRevision(report, out, dependencies, dep);
93 for (IvyNode dep : report.getNodes(mid)) {
94 outputRevision(report, out, dependencies, dep);
10095 }
10196 out.println("\t\t</module>");
10297 }
105100 out.flush();
106101 }
107102
108 private void ouputRevision(ConfigurationResolveReport report, PrintWriter out,
109 List dependencies, IvyNode dep) {
110 Map extraAttributes;
103 private void outputRevision(ConfigurationResolveReport report, PrintWriter out,
104 List<ModuleRevisionId> dependencies, IvyNode dep) {
105 Map<String, String> extraAttributes;
111106 ModuleDescriptor md = null;
112107 if (dep.getModuleRevision() != null) {
113108 md = dep.getModuleRevision().getDescriptor();
114109 }
115 StringBuffer details = new StringBuffer();
110 StringBuilder details = new StringBuilder();
116111 if (dep.isLoaded()) {
117112 details.append(" status=\"");
118113 details.append(XMLHelper.escape(dep.getDescriptor().getStatus()));
144139 if (md != null && md.getHomePage() != null) {
145140 details.append(" homepage=\"").append(XMLHelper.escape(md.getHomePage())).append("\"");
146141 }
147 extraAttributes = md != null ? md.getExtraAttributes() : dep.getResolvedId()
148 .getExtraAttributes();
149 for (Iterator iterator = extraAttributes.keySet().iterator(); iterator.hasNext();) {
150 String attName = (String) iterator.next();
151 details.append(" extra-").append(attName).append("=\"")
152 .append(XMLHelper.escape(extraAttributes.get(attName).toString())).append("\"");
153 }
154 String defaultValue = dep.getDescriptor() != null ? " default=\""
155 + dep.getDescriptor().isDefault() + "\"" : "";
156 int position = dependencies.indexOf(dep.getResolvedId());
157 out.println("\t\t\t<revision name=\""
158 + XMLHelper.escape(dep.getResolvedId().getRevision())
159 + "\""
160 + (dep.getResolvedId().getBranch() == null ? "" : " branch=\""
161 + XMLHelper.escape(dep.getResolvedId().getBranch()) + "\"") + details
162 + " downloaded=\"" + dep.isDownloaded() + "\"" + " searched=\"" + dep.isSearched()
163 + "\"" + defaultValue + " conf=\""
164 + toString(dep.getConfigurations(report.getConfiguration())) + "\""
165 + " position=\"" + position + "\">");
142 extraAttributes = (md != null)
143 ? md.getQualifiedExtraAttributes()
144 : dep.getResolvedId().getQualifiedExtraAttributes();
145 details.append(extraToString(extraAttributes, SEPARATOR));
146 out.println(String.format("\t\t\t<revision name=\"%s\"%s%s downloaded=\"%s\" searched=\"%s\"%s conf=\"%s\" position=\"%d\">",
147 XMLHelper.escape(dep.getResolvedId().getRevision()),
148 (dep.getResolvedId().getBranch() == null) ? "" : " branch=\""
149 + XMLHelper.escape(dep.getResolvedId().getBranch()) + "\"",
150 details, dep.isDownloaded(), dep.isSearched(),
151 (dep.getDescriptor() == null) ? "" : " default=\""
152 + dep.getDescriptor().isDefault() + "\"",
153 XMLHelper.escape(joinArray(dep.getConfigurations(report.getConfiguration()), ", ")),
154 dependencies.indexOf(dep.getResolvedId())));
166155 if (md != null) {
167156 License[] licenses = md.getLicenses();
168 for (int i = 0; i < licenses.length; i++) {
169 String lurl;
170 if (licenses[i].getUrl() != null) {
171 lurl = " url=\"" + XMLHelper.escape(licenses[i].getUrl()) + "\"";
172 } else {
173 lurl = "";
174 }
175 out.println("\t\t\t\t<license name=\"" + XMLHelper.escape(licenses[i].getName())
176 + "\"" + lurl + "/>");
157 for (License license : licenses) {
158 out.println(String.format("\t\t\t\t<license name=\"%s\"%s/>",
159 XMLHelper.escape(license.getName()),
160 license.getUrl() == null ? "" : " url=\"" + XMLHelper.escape(license.getUrl()) + "\""));
177161 }
178162 }
179163 outputMetadataArtifact(out, dep);
183167 out.println("\t\t\t</revision>");
184168 }
185169
170 private String extraToString(Map<String, String> extraAttributes, String prefix) {
171 StringBuilder sb = new StringBuilder();
172 for (Map.Entry<String, String> entry : extraAttributes.entrySet()) {
173 if (sb.length() > 0 && !SEPARATOR.equals(prefix)) {
174 sb.append(System.lineSeparator());
175 }
176
177 sb.append(prefix);
178 sb.append(ExtendableItemHelper.encodeAttribute(entry.getKey(), "extra-"));
179 sb.append("=\"");
180 sb.append(XMLHelper.escape(entry.getValue()));
181 sb.append("\"");
182 }
183 return sb.toString();
184 }
185
186186 private void outputEvictionInformation(ConfigurationResolveReport report, PrintWriter out,
187187 IvyNode dep) {
188188 if (dep.isEvicted(report.getConfiguration())) {
189189 EvictionData ed = dep.getEvictedData(report.getConfiguration());
190 Collection selected = ed.getSelected();
190 Collection<IvyNode> selected = ed.getSelected();
191191 if (selected != null) {
192 for (Iterator it3 = selected.iterator(); it3.hasNext();) {
193 IvyNode sel = (IvyNode) it3.next();
192 for (IvyNode sel : selected) {
194193 out.println("\t\t\t\t<evicted-by rev=\""
195194 + XMLHelper.escape(sel.getResolvedId().getRevision()) + "\"/>");
196195 }
228227 }
229228
230229 private void outputCallers(ConfigurationResolveReport report, PrintWriter out, IvyNode dep) {
231 Caller[] callers = dep.getCallers(report.getConfiguration());
232 for (int i = 0; i < callers.length; i++) {
233 StringBuffer callerDetails = new StringBuffer();
234 Map callerExtraAttributes = callers[i].getDependencyDescriptor().getExtraAttributes();
235 for (Iterator iterator = callerExtraAttributes.keySet().iterator(); iterator.hasNext();) {
236 String attName = (String) iterator.next();
237 callerDetails.append(" extra-").append(attName).append("=\"")
238 .append(XMLHelper.escape(callerExtraAttributes.get(attName).toString()))
239 .append("\"");
240 }
241
242 out.println("\t\t\t\t<caller organisation=\""
243 + XMLHelper.escape(callers[i].getModuleRevisionId().getOrganisation())
244 + "\""
245 + " name=\""
246 + XMLHelper.escape(callers[i].getModuleRevisionId().getName())
247 + "\""
248 + " conf=\""
249 + XMLHelper.escape(toString(callers[i].getCallerConfigurations()))
250 + "\""
251 + " rev=\""
252 + XMLHelper.escape(callers[i].getAskedDependencyId(dep.getData()).getRevision())
253 + "\""
254 + " rev-constraint-default=\""
255 + XMLHelper.escape(callers[i].getDependencyDescriptor()
256 .getDependencyRevisionId().getRevision())
257 + "\""
258 + " rev-constraint-dynamic=\""
259 + XMLHelper.escape(callers[i].getDependencyDescriptor()
260 .getDynamicConstraintDependencyRevisionId().getRevision()) + "\""
261 + " callerrev=\""
262 + XMLHelper.escape(callers[i].getModuleRevisionId().getRevision()) + "\""
263 + callerDetails + "/>");
230 for (Caller caller : dep.getCallers(report.getConfiguration())) {
231 final DependencyDescriptor dependencyDescriptor = caller.getDependencyDescriptor();
232 out.println(String.format("\t\t\t\t<caller organisation=\"%s\" name=\"%s\" conf=\"%s\" rev=\"%s\" rev-constraint-default=\"%s\" rev-constraint-dynamic=\"%s\" callerrev=\"%s\"%s/>",
233 XMLHelper.escape(caller.getModuleRevisionId().getOrganisation()),
234 XMLHelper.escape(caller.getModuleRevisionId().getName()),
235 XMLHelper.escape(joinArray(caller.getCallerConfigurations(), ", ")),
236 XMLHelper.escape(caller.getAskedDependencyId().getRevision()),
237 XMLHelper.escape(dependencyDescriptor.getDependencyRevisionId().getRevision()),
238 XMLHelper.escape(dependencyDescriptor.getDynamicConstraintDependencyRevisionId().getRevision()),
239 XMLHelper.escape(caller.getModuleRevisionId().getRevision()),
240 extraToString(dependencyDescriptor.getQualifiedExtraAttributes(), SEPARATOR)));
264241 }
265242 }
266243
267244 private void outputArtifacts(ConfigurationResolveReport report, PrintWriter out, IvyNode dep) {
268 Map extraAttributes;
269 ArtifactDownloadReport[] adr = report.getDownloadReports(dep.getResolvedId());
270245 out.println("\t\t\t\t<artifacts>");
271 for (int i = 0; i < adr.length; i++) {
272 out.print("\t\t\t\t\t<artifact name=\"" + XMLHelper.escape(adr[i].getName())
273 + "\" type=\"" + XMLHelper.escape(adr[i].getType()) + "\" ext=\""
274 + XMLHelper.escape(adr[i].getExt()) + "\"");
275 extraAttributes = adr[i].getArtifact().getExtraAttributes();
276 for (Iterator iterator = extraAttributes.keySet().iterator(); iterator.hasNext();) {
277 String attName = (String) iterator.next();
278 out.print(" extra-" + attName + "=\""
279 + XMLHelper.escape(extraAttributes.get(attName).toString()) + "\"");
280 }
281 out.print(" status=\"" + XMLHelper.escape(adr[i].getDownloadStatus().toString()) + "\"");
282 out.print(" details=\"" + XMLHelper.escape(adr[i].getDownloadDetails()) + "\"");
283 out.print(" size=\"" + adr[i].getSize() + "\"");
284 out.print(" time=\"" + adr[i].getDownloadTimeMillis() + "\"");
285 if (adr[i].getLocalFile() != null) {
246 for (ArtifactDownloadReport adr : report.getDownloadReports(dep.getResolvedId())) {
247 out.print("\t\t\t\t\t<artifact name=\"" + XMLHelper.escape(adr.getName())
248 + "\" type=\"" + XMLHelper.escape(adr.getType()) + "\" ext=\""
249 + XMLHelper.escape(adr.getExt()) + "\"");
250 out.print(extraToString(adr.getArtifact().getQualifiedExtraAttributes(), SEPARATOR));
251 out.print(" status=\"" + XMLHelper.escape(adr.getDownloadStatus().toString()) + "\"");
252 out.print(" details=\"" + XMLHelper.escape(adr.getDownloadDetails()) + "\"");
253 out.print(" size=\"" + adr.getSize() + "\"");
254 out.print(" time=\"" + adr.getDownloadTimeMillis() + "\"");
255 if (adr.getLocalFile() != null) {
286256 out.print(" location=\""
287 + XMLHelper.escape(adr[i].getLocalFile().getAbsolutePath()) + "\"");
288 }
289 if (adr[i].getUnpackedLocalFile() != null) {
257 + XMLHelper.escape(adr.getLocalFile().getAbsolutePath()) + "\"");
258 }
259 if (adr.getUnpackedLocalFile() != null) {
290260 out.print(" unpackedFile=\""
291 + XMLHelper.escape(adr[i].getUnpackedLocalFile().getAbsolutePath()) + "\"");
292 }
293
294 ArtifactOrigin origin = adr[i].getArtifactOrigin();
261 + XMLHelper.escape(adr.getUnpackedLocalFile().getAbsolutePath()) + "\"");
262 }
263
264 ArtifactOrigin origin = adr.getArtifactOrigin();
295265 if (origin != null) {
296266 out.println(">");
297267 out.println("\t\t\t\t\t\t<origin-location is-local=\""
305275 out.println("\t\t\t\t</artifacts>");
306276 }
307277
308 private String toString(String[] strs) {
309 StringBuffer buf = new StringBuffer();
310 for (int i = 0; i < strs.length; i++) {
311 buf.append(strs[i]);
312 if (i + 1 < strs.length) {
313 buf.append(", ");
314 }
315 }
316 return XMLHelper.escape(buf.toString());
317 }
318278 }
0 <?xml version="1.0" encoding="ISO-8859-1"?>
0 <?xml version="1.0" encoding="UTF-8"?>
11 <!--
22 Licensed to the Apache Software Foundation (ASF) under one
33 or more contributor license agreements. See the NOTICE file
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
19 <xsl:stylesheet version="1.0"
20 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
19 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
2120 <xsl:output method="text"/>
2221 <xsl:template match="/ivy-report">
2322 <xsl:text>/* * directed graph dot input file. * * generated by ivy report */
2423 digraph G {</xsl:text>
2524 <xsl:for-each select="dependencies/module">
26 <xsl:text>"</xsl:text><xsl:value-of select="@name"/><xsl:text>"</xsl:text>
25 <xsl:text>"</xsl:text><xsl:value-of select="@name"/><xsl:text>"</xsl:text>
2726 </xsl:for-each>
2827 <xsl:for-each select="dependencies/module/revision[not(@evicted)]/caller[@organisation!='caller']">
29 <xsl:text>"</xsl:text><xsl:value-of select="@name"/><xsl:text>" -&gt; "</xsl:text><xsl:value-of select="../../@name"/><xsl:text>";</xsl:text>
28 <xsl:text>"</xsl:text><xsl:value-of select="@name"/><xsl:text>" -&gt; "</xsl:text><xsl:value-of select="../../@name"/><xsl:text>";</xsl:text>
3029 </xsl:for-each>
3130 <xsl:text>}</xsl:text>
3231 </xsl:template>
0 <?xml version="1.0" encoding="UTF-8"?>
01 <!--
12 Licensed to the Apache Software Foundation (ASF) under one
23 or more contributor license agreements. See the NOTICE file
67 "License"); you may not use this file except in compliance
78 with the License. You may obtain a copy of the License at
89
9 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1011
1112 Unless required by applicable law or agreed to in writing,
1213 software distributed under the License is distributed on an
1314 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1415 KIND, either express or implied. See the License for the
1516 specific language governing permissions and limitations
16 under the License.
17 under the License.
1718 -->
18 <xsl:stylesheet version="1.0"
19 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
19 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
2020 <xsl:output method="text"/>
2121 <xsl:template match="/ivy-report">
2222 /* * directed graph dot input file. * * generated by ivy report */
2323 digraph G {
24 "<xsl:value-of select="info/@organisation"/>-<xsl:value-of select="info/@module"/>" [label="<xsl:value-of select="info/@module"/>"];
25 <xsl:for-each select="dependencies/module">
26 "<xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/>" [label="<xsl:value-of select="@name"/>
27 <xsl:for-each select="revision">
24 "<xsl:value-of select="info/@organisation"/>-<xsl:value-of select="info/@module"/>" [label="<xsl:value-of select="info/@module"/>"];
25 <xsl:for-each select="dependencies/module">
26 "<xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/>" [label="<xsl:value-of select="@name"/>
27 <xsl:for-each select="revision">
2828 <xsl:text>\n</xsl:text>
2929 <xsl:value-of select="@name"/><xsl:if test="@error"> (error)</xsl:if><xsl:if test="@evicted"> (evicted)</xsl:if>
30 </xsl:for-each>
31 <xsl:text>"];
30 </xsl:for-each>
31 <xsl:text>"];
3232 </xsl:text>
33 </xsl:for-each>
34 <xsl:for-each select="dependencies/module/revision[not(@evicted)]/caller">
35 <xsl:text>"</xsl:text>
36 <xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/>
37 <xsl:text>" -> "</xsl:text>
38 <xsl:value-of select="../../@organisation"/>-<xsl:value-of select="../../@name"/>
39 <xsl:text>" [label="</xsl:text>
40 <xsl:value-of select="@rev"/>
41 <xsl:text>"]</xsl:text>
42 <xsl:text>;
33 </xsl:for-each>
34 <xsl:for-each select="dependencies/module/revision[not(@evicted)]/caller">
35 <xsl:text>"</xsl:text>
36 <xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/>
37 <xsl:text>" -> "</xsl:text>
38 <xsl:value-of select="../../@organisation"/>-<xsl:value-of select="../../@name"/>
39 <xsl:text>" [label="</xsl:text>
40 <xsl:value-of select="@rev"/>
41 <xsl:text>"]</xsl:text>
42 <xsl:text>;
4343 </xsl:text>
44 </xsl:for-each>
45 <xsl:text>}</xsl:text>
44 </xsl:for-each>
45 <xsl:text>}</xsl:text>
4646 </xsl:template>
4747
4848 </xsl:stylesheet>
0 <?xml version="1.0" encoding="ISO-8859-1"?>
0 <?xml version="1.0" encoding="UTF-8"?>
11 <!--
22 Licensed to the Apache Software Foundation (ASF) under one
33 or more contributor license agreements. See the NOTICE file
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
19 <xsl:stylesheet version="1.0"
20 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
19 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
2120
2221 <xsl:template match="/ivy-report">
23 <graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"
22 <graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"
2423 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
25 xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd"
24 xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd"
2625 xmlns:y="http://www.yworks.com/xml/graphml">
2726 <key id="d0" for="node" yfiles.type="nodegraphics"/>
2827 <key id="d1" for="edge" yfiles.type="edgegraphics"/>
3332 <data key="d0" >
3433 <y:ShapeNode>
3534 <y:Fill color="#FFFFCC" transparent="false"/>
36 <y:BorderStyle type="line" width="1.0" color="#000000" />
35 <y:BorderStyle type="line" width="1.0" color="#000000"/>
3736 <y:NodeLabel visible="true" alignment="center" fontFamily="Dialog" fontSize="12" fontStyle="plain" textColor="#000000" modelName="internal" modelPosition="c" autoSizePolicy="center">
3837 <xsl:value-of select="@name"/>
3938 </y:NodeLabel>
4948 <xsl:attribute name="target"><xsl:value-of select="../../@organisation"/>-<xsl:value-of select="../../@name"/></xsl:attribute>
5049 <data key="d1">
5150 <y:PolyLineEdge>
52 <y:LineStyle type="line" width="1.0" color="#000000" />
51 <y:LineStyle type="line" width="1.0" color="#000000"/>
5352 <y:Arrows source="none" target="standard"/>
5453 <y:BendStyle smoothed="false"/>
5554 </y:PolyLineEdge>
5756 </xsl:element>
5857 </xsl:for-each>
5958 </graph>
60 </graphml>
59 </graphml>
6160 </xsl:template>
6261
6362 </xsl:stylesheet>
0 <?xml version="1.0" encoding="ISO-8859-1"?>
0 <?xml version="1.0" encoding="UTF-8"?>
11 <!--
22 Licensed to the Apache Software Foundation (ASF) under one
33 or more contributor license agreements. See the NOTICE file
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
19 <xsl:stylesheet version="1.0"
20 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
19 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
2120
2221 <xsl:template match="/ivy-report">
23 <graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"
22 <graphml xmlns="http://graphml.graphdrawing.org/xmlns/graphml"
2423 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
25 xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd"
24 xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/graphml http://www.yworks.com/xml/schema/graphml/1.0/ygraphml.xsd"
2625 xmlns:y="http://www.yworks.com/xml/graphml">
2726 <key id="d0" for="node" yfiles.type="nodegraphics"/>
2827 <key id="d1" for="edge" yfiles.type="edgegraphics"/>
3231 <data key="d0" >
3332 <y:ShapeNode>
3433 <y:Fill color="#CCCCFF" transparent="false"/>
35 <y:BorderStyle type="line" width="1.0" color="#000000" />
34 <y:BorderStyle type="line" width="1.0" color="#000000"/>
3635 <y:NodeLabel visible="true" alignment="center" fontFamily="Dialog" fontSize="12" fontStyle="plain" textColor="#000000" modelName="internal" modelPosition="c" autoSizePolicy="center">
3736 <xsl:value-of select="info/@module"/>
3837 </y:NodeLabel>
4645 <data key="d0" >
4746 <y:ShapeNode>
4847 <y:Fill color="#FFFFCC" transparent="false"/>
49 <y:BorderStyle type="line" width="1.0" color="#000000" />
48 <y:BorderStyle type="line" width="1.0" color="#000000"/>
5049 <y:NodeLabel visible="true" alignment="center" fontFamily="Dialog" fontSize="12" fontStyle="plain" textColor="#000000" modelName="internal" modelPosition="c" autoSizePolicy="center">
5150 <xsl:value-of select="@name"/>
5251 <xsl:for-each select="revision">
6766 <xsl:attribute name="target"><xsl:value-of select="../../@organisation"/>-<xsl:value-of select="../../@name"/></xsl:attribute>
6867 <data key="d1">
6968 <y:PolyLineEdge>
70 <y:LineStyle type="line" width="1.0" color="#000000" />
69 <y:LineStyle type="line" width="1.0" color="#000000"/>
7170 <y:Arrows source="none" target="standard"/>
7271 <y:EdgeLabel visible="true" alignment="center" fontFamily="Dialog" fontSize="12" fontStyle="plain" textColor="#000000" modelName="free" modelPosition="anywhere" preferredPlacement="target" distance="2.0" ratio="0.5">
7372 <xsl:value-of select="@rev"/>
7877 </xsl:element>
7978 </xsl:for-each>
8079 </graph>
81 </graphml>
80 </graphml>
8281 </xsl:template>
8382
8483 </xsl:stylesheet>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1414 * limitations under the License.
1515 *
1616 */
17
17
1818 body {
19 font-family:"Trebuchet MS",Verdana,Geneva,Arial,Helvetica,sans-serif;
20 font-size:small;
19 font-family: "Trebuchet MS",Verdana,Geneva,Arial,Helvetica,sans-serif;
20 font-size: small;
2121 }
2222
2323 div#logo {
24 float: right;
25 padding-left: 10px;
26 padding-bottom: 10px;
24 float: right;
25 padding-left: 10px;
26 padding-bottom: 10px;
2727 background: white;
2828 text-align: center;
2929 }
3030
3131 #logo img {
32 border: 0;
32 border: 0;
3333 }
3434
3535 div#date {
36 font-style: italic;
37 padding-left: 60px;
38 padding-bottom: 40px;
36 font-style: italic;
37 padding-left: 60px;
38 padding-bottom: 40px;
3939 }
4040
4141
4242 h1 {
43 margin-bottom:2px;
44
45 border-color:#7A9437;
46 border-style:solid;
47 border-width:0 0 3px 0;
43 margin-bottom: 2px;
44
45 border-color: #7A9437;
46 border-style: solid;
47 border-width: 0 0 3px 0;
4848 }
4949
5050 span#module {
51 color:#7A9437;
52 text-decoration:none;
51 color: #7A9437;
52 text-decoration: none;
5353 }
5454
5555 span#organisation {
56 color:black;
57 text-decoration:none;
56 color: black;
57 text-decoration: none;
5858 }
5959
6060 #confmenu {
61 color: #000;
62 border-bottom: 2px solid black;
63 margin: 12px 0px 0px 0px;
64 padding: 0px;
65 z-index: 1;
66 padding-left: 10px
61 color: #000;
62 border-bottom: 2px solid black;
63 margin: 12px 0px 0px 0px;
64 padding: 0px;
65 z-index: 1;
66 padding-left: 10px
6767 }
6868
6969 #confmenu li {
70 display: inline;
71 overflow: hidden;
72 list-style-type: none;
70 display: inline;
71 overflow: hidden;
72 list-style-type: none;
7373 }
7474
7575 #confmenu a, a.active {
76 color: #DEDECF;
77 background: #898B5E;
78 font: bold 1em "Trebuchet MS", Arial, sans-serif;
79 border: 2px solid black;
80 padding: 2px 5px 0px 5px;
81 text-decoration: none;
76 color: #DEDECF;
77 background: #898B5E;
78 font: bold 1em "Trebuchet MS", Arial, sans-serif;
79 border: 2px solid black;
80 padding: 2px 5px 0px 5px;
81 text-decoration: none;
8282 }
8383
8484 /*
8787 */
8888
8989 #confmenu a.active {
90 color: #7A9437;
91 background: #DEE4CD;
92 border-bottom: 3px solid #DEE4CD;
90 color: #7A9437;
91 background: #DEE4CD;
92 border-bottom: 3px solid #DEE4CD;
9393 }
9494
9595 #confmenu a:hover {
96 color: #fff;
97 background: #ADC09F;
96 color: #fff;
97 background: #ADC09F;
9898 }
9999
100100 #confmenu a:visited {
101 color: #DEDECF;
101 color: #DEDECF;
102102 }
103103
104104 #confmenu a.active:visited {
105 color: #7A9437;
105 color: #7A9437;
106106 }
107107
108108 #confmenu a.active:hover {
109 background: #DEE4CD;
110 color: #DEDECF;
109 background: #DEE4CD;
110 color: #DEDECF;
111111 }
112112
113113 #content {
114 background: #DEE4CD;
115 padding: 20px;
116 border: 2px solid black;
117 border-top: none;
118 z-index: 2;
114 background: #DEE4CD;
115 padding: 20px;
116 border: 2px solid black;
117 border-top: none;
118 z-index: 2;
119119 }
120120
121121 #content a {
122 text-decoration: none;
123 color: #E8E9BE;
124 }
125
126 #content a:hover {
127 background: #898B5E;
128 }
129
122 text-decoration: none;
123 color: #E8E9BE;
124 }
125
126 #content a:hover {
127 background: #898B5E;
128 }
130129
131130 h2 {
132 margin-bottom:2px;
133 font-size:medium;
134
135 border-color:#7A9437;
136 border-style:solid;
137 border-width:0 0 2px 0;
131 margin-bottom: 2px;
132 font-size: medium;
133 border-color: #7A9437;
134 border-style: solid;
135 border-width: 0 0 2px 0;
138136 }
139137
140138 h3 {
141 margin-top:30px;
142 margin-bottom:2px;
139 margin-top: 30px;
140 margin-bottom: 2px;
143141 padding: 5 5 5 0;
144142 font-size: 24px;
145 border-style:solid;
146 border-width:0 0 2px 0;
143 border-style: solid;
144 border-width: 0 0 2px 0;
147145 }
148146
149147 h4 {
150 margin-bottom:2px;
151 margin-top:2px;
152 font-size:medium;
153
154 border-color:#7A9437;
155 border-style:dashed;
156 border-width:0 0 1px 0;
148 margin-bottom: 2px;
149 margin-top: 2px;
150 font-size: medium;
151 border-color: #7A9437;
152 border-style: dashed;
153 border-width: 0 0 1px 0;
157154 }
158155
159156 h5 {
160 margin-bottom:2px;
161 margin-top:2px;
162 margin-left:20px;
163 font-size:medium;
157 margin-bottom: 2px;
158 margin-top: 2px;
159 margin-left: 20px;
160 font-size: medium;
164161 }
165162
166163 span.resolved {
167 padding-left: 15px;
168 font-weight: 500;
169 font-size: small;
170 }
171
164 padding-left: 15px;
165 font-weight: 500;
166 font-size: small;
167 }
172168
173169 #content table {
174 border-collapse:collapse;
175 width:90%;
176 margin:auto;
177 margin-top: 5px;
170 border-collapse: collapse;
171 width: 90%;
172 margin: auto;
173 margin-top: 5px;
178174 }
179175 #content thead {
180 background-color:#CED4BD;
181 border:1px solid #7A9437;
176 background-color: #CED4BD;
177 border: 1px solid #7A9437;
182178 }
183179 #content tbody {
184 border-collapse:collapse;
185 background-color:#FFFFFF;
186 border:1px solid #7A9437;
180 border-collapse: collapse;
181 background-color: #FFFFFF;
182 border: 1px solid #7A9437;
187183 }
188184
189185 #content th {
190 font-family:monospace;
191 border:1px solid #7A9437;
192 padding:5px;
186 font-family: monospace;
187 border: 1px solid #7A9437;
188 padding: 5px;
193189 }
194190
195191 #content td {
196 border:1px dotted #7A9437;
197 padding:0 3 0 3;
192 border: 1px dotted #7A9437;
193 padding: 0 3 0 3;
198194 }
199195
200196 #content table a {
201 color:#7A9437;
202 text-decoration:none;
197 color: #7A9437;
198 text-decoration: none;
203199 }
204200
205201 #content table a:hover {
206 background-color:#CED4BD;
207 color:#7A9437;
208 }
209
210
202 background-color: #CED4BD;
203 color: #7A9437;
204 }
211205
212206 table.deps {
213 border-collapse:collapse;
214 width:90%;
215 margin:auto;
216 margin-top: 5px;
207 border-collapse: collapse;
208 width: 90%;
209 margin: auto;
210 margin-top: 5px;
217211 }
218212
219213 table.deps thead {
220 background-color:#CED4BD;
221 border:1px solid #7A9437;
214 background-color: #CED4BD;
215 border: 1px solid #7A9437;
222216 }
223217 table.deps tbody {
224 border-collapse:collapse;
225 background-color:#FFFFFF;
226 border:1px solid #7A9437;
218 border-collapse: collapse;
219 background-color: #FFFFFF;
220 border: 1px solid #7A9437;
227221 }
228222
229223 table.deps th {
230 font-family:monospace;
231 border:1px solid #7A9437;
232 padding:2;
224 font-family: monospace;
225 border: 1px solid #7A9437;
226 padding: 2;
233227 }
234228
235229 table.deps td {
236 border:1px dotted #7A9437;
237 padding:0 3 0 3;
238 }
239
240
241
242
230 border: 1px dotted #7A9437;
231 padding: 0 3 0 3;
232 }
243233
244234 table.header {
245 border:0;
246 width:90%;
247 margin:auto;
248 margin-top: 5px;
235 border: 0;
236 width: 90%;
237 margin: auto;
238 margin-top: 5px;
249239 }
250240
251241 table.header thead {
252 border:0;
253 }
242 border: 0;
243 }
244
254245 table.header tbody {
255 border:0;
256 }
246 border: 0;
247 }
248
257249 table.header tr {
258 padding:0px;
259 border:0;
260 }
250 padding: 0px;
251 border: 0;
252 }
253
261254 table.header td {
262 padding:0 3 0 3;
263 border:0;
255 padding: 0 3 0 3;
256 border: 0;
264257 }
265258
266259 td.title {
267 width:150px;
268 margin-right:15px;
269
270 font-size:small;
271 font-weight:700;
260 width: 150px;
261 margin-right: 15px;
262 font-size: small;
263 font-weight: 700;
272264 }
273265
274266 td.title:first-letter {
275 color:#7A9437;
276 background-color:transparent;
277 }
278
267 color: #7A9437;
268 background-color: transparent;
269 }
0 <?xml version="1.0" encoding="ISO-8859-1"?>
0 <?xml version="1.0" encoding="UTF-8"?>
11 <!--
22 Licensed to the Apache Software Foundation (ASF) under one
33 or more contributor license agreements. See the NOTICE file
77 "License"); you may not use this file except in compliance
88 with the License. You may obtain a copy of the License at
99
10 http://www.apache.org/licenses/LICENSE-2.0
10 https://www.apache.org/licenses/LICENSE-2.0
1111
1212 Unless required by applicable law or agreed to in writing,
1313 software distributed under the License is distributed on an
1414 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1515 KIND, either express or implied. See the License for the
1616 specific language governing permissions and limitations
17 under the License.
17 under the License.
1818 -->
19 <xsl:stylesheet version="1.0"
20 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
21
22 <xsl:param name="confs" select="/ivy-report/info/@confs"/>
23 <xsl:param name="extension" select="'xml'"/>
24
25 <xsl:variable name="myorg" select="/ivy-report/info/@organisation"/>
26 <xsl:variable name="mymod" select="/ivy-report/info/@module"/>
27 <xsl:variable name="myconf" select="/ivy-report/info/@conf"/>
28
29 <xsl:variable name="modules" select="/ivy-report/dependencies/module"/>
30 <xsl:variable name="conflicts" select="$modules[count(revision) > 1]"/>
31
32 <xsl:variable name="revisions" select="$modules/revision"/>
33 <xsl:variable name="evicteds" select="$revisions[@evicted]"/>
34 <xsl:variable name="downloadeds" select="$revisions[@downloaded='true']"/>
35 <xsl:variable name="searcheds" select="$revisions[@searched='true']"/>
36 <xsl:variable name="errors" select="$revisions[@error]"/>
37
38 <xsl:variable name="artifacts" select="$revisions/artifacts/artifact"/>
19 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
20
21 <xsl:param name="confs" select="/ivy-report/info/@confs"/>
22 <xsl:param name="extension" select="'xml'"/>
23
24 <xsl:variable name="myorg" select="/ivy-report/info/@organisation"/>
25 <xsl:variable name="mymod" select="/ivy-report/info/@module"/>
26 <xsl:variable name="myconf" select="/ivy-report/info/@conf"/>
27
28 <xsl:variable name="modules" select="/ivy-report/dependencies/module"/>
29 <xsl:variable name="conflicts" select="$modules[count(revision) > 1]"/>
30
31 <xsl:variable name="revisions" select="$modules/revision"/>
32 <xsl:variable name="evicteds" select="$revisions[@evicted]"/>
33 <xsl:variable name="downloadeds" select="$revisions[@downloaded='true']"/>
34 <xsl:variable name="searcheds" select="$revisions[@searched='true']"/>
35 <xsl:variable name="errors" select="$revisions[@error]"/>
36
37 <xsl:variable name="artifacts" select="$revisions/artifacts/artifact"/>
3938 <xsl:variable name="cacheartifacts" select="$artifacts[@status='no']"/>
4039 <xsl:variable name="dlartifacts" select="$artifacts[@status='successful']"/>
4140 <xsl:variable name="faileds" select="$artifacts[@status='failed']"/>
4241 <xsl:variable name="artifactsok" select="$artifacts[@status!='failed']"/>
4342
4443 <xsl:template name="calling">
45 <xsl:param name="org" />
46 <xsl:param name="mod" />
47 <xsl:param name="rev" />
44 <xsl:param name="org"/>
45 <xsl:param name="mod"/>
46 <xsl:param name="rev"/>
4847 <xsl:if test="count($modules/revision/caller[(@organisation=$org and @name=$mod) and @callerrev=$rev]) = 0">
4948 <table><tr><td>
5049 No dependency
6564 </tr>
6665 </thead>
6766 <tbody>
68 <xsl:for-each select="$modules/revision/caller[(@organisation=$org and @name=$mod) and @callerrev=$rev]">
67 <xsl:for-each select="$modules/revision/caller[(@organisation=$org and @name=$mod) and @callerrev=$rev]">
6968 <xsl:call-template name="called">
70 <xsl:with-param name="callstack" select="concat($org, string('/'), $mod)"/>
71 <xsl:with-param name="indent" select="string('')"/>
72 <xsl:with-param name="revision" select=".."/>
69 <xsl:with-param name="callstack" select="concat($org, string('/'), $mod)"/>
70 <xsl:with-param name="indent" select="string('')"/>
71 <xsl:with-param name="revision" select=".."/>
7372 </xsl:call-template>
74 </xsl:for-each>
73 </xsl:for-each>
7574 </tbody>
7675 </table>
7776 </xsl:if>
9089 <xsl:param name="status" select="$revision/@status"/>
9190 <tr>
9291 <td>
93 <xsl:element name="a">
94 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/></xsl:attribute>
95 <xsl:value-of select="concat($indent, ' ')"/>
96 <xsl:value-of select="$module"/>
97 by
98 <xsl:value-of select="$organisation"/>
99 </xsl:element>
92 <xsl:element name="a">
93 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/></xsl:attribute>
94 <xsl:value-of select="concat($indent, ' ')"/>
95 <xsl:value-of select="$module"/>
96 by
97 <xsl:value-of select="$organisation"/>
98 </xsl:element>
10099 </td>
101100 <td>
102 <xsl:element name="a">
103 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/>-<xsl:value-of select="$rev"/></xsl:attribute>
104 <xsl:value-of select="$rev"/>
105 </xsl:element>
101 <xsl:element name="a">
102 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/>-<xsl:value-of select="$rev"/></xsl:attribute>
103 <xsl:value-of select="$rev"/>
104 </xsl:element>
106105 </td>
107106 <td align="center">
108 <xsl:value-of select="$status"/>
107 <xsl:value-of select="$status"/>
109108 </td>
110109 <td align="center">
111 <xsl:value-of select="$resolver"/>
110 <xsl:value-of select="$resolver"/>
112111 </td>
113112 <td align="center">
114 <xsl:value-of select="$isdefault"/>
113 <xsl:value-of select="$isdefault"/>
115114 </td>
116115 <td align="center">
117 <xsl:call-template name="licenses">
118 <xsl:with-param name="revision" select="$revision"/>
119 </xsl:call-template>
116 <xsl:call-template name="licenses">
117 <xsl:with-param name="revision" select="$revision"/>
118 </xsl:call-template>
120119 </td>
121120 <td align="center">
122 <xsl:value-of select="round(sum($revision/artifacts/artifact/@size) div 1024)"/> kB
121 <xsl:value-of select="round(sum($revision/artifacts/artifact/@size) div 1024)"/> kB
123122 </td>
124123 <td align="center">
125 <xsl:call-template name="icons">
126 <xsl:with-param name="revision" select="$revision"/>
127 </xsl:call-template>
124 <xsl:call-template name="icons">
125 <xsl:with-param name="revision" select="$revision"/>
126 </xsl:call-template>
128127 </td>
129128 </tr>
130129 <xsl:if test="not($revision/@evicted)">
131 <xsl:if test="not(contains($callstack, concat($organisation, string('/'), $module)))">
132 <xsl:for-each select="$modules/revision/caller[(@organisation=$organisation and @name=$module) and @callerrev=$rev]">
133 <xsl:call-template name="called">
134 <xsl:with-param name="callstack" select="concat($callstack, string('#'), $organisation, string('/'), $module)"/>
135 <xsl:with-param name="indent" select="concat($indent, string('---'))"/>
136 <xsl:with-param name="revision" select=".."/>
137 </xsl:call-template>
138 </xsl:for-each>
139 </xsl:if>
130 <xsl:if test="not(contains($callstack, concat($organisation, string('/'), $module)))">
131 <xsl:for-each select="$modules/revision/caller[(@organisation=$organisation and @name=$module) and @callerrev=$rev]">
132 <xsl:call-template name="called">
133 <xsl:with-param name="callstack" select="concat($callstack, string('#'), $organisation, string('/'), $module)"/>
134 <xsl:with-param name="indent" select="concat($indent, string('---'))"/>
135 <xsl:with-param name="revision" select=".."/>
136 </xsl:call-template>
137 </xsl:for-each>
138 </xsl:if>
140139 </xsl:if>
141140 </xsl:template>
142141
143142 <xsl:template name="licenses">
144 <xsl:param name="revision"/>
145 <xsl:for-each select="$revision/license">
146 <span style="padding-right:3px;">
147 <xsl:if test="@url">
148 <xsl:element name="a">
149 <xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute>
150 <xsl:value-of select="@name"/>
151 </xsl:element>
152 </xsl:if>
153 <xsl:if test="not(@url)">
154 <xsl:value-of select="@name"/>
155 </xsl:if>
156 </span>
157 </xsl:for-each>
143 <xsl:param name="revision"/>
144 <xsl:for-each select="$revision/license">
145 <span style="padding-right:3px;">
146 <xsl:if test="@url">
147 <xsl:element name="a">
148 <xsl:attribute name="href"><xsl:value-of select="@url"/></xsl:attribute>
149 <xsl:value-of select="@name"/>
150 </xsl:element>
151 </xsl:if>
152 <xsl:if test="not(@url)">
153 <xsl:value-of select="@name"/>
154 </xsl:if>
155 </span>
156 </xsl:for-each>
158157 </xsl:template>
159158
160159 <xsl:template name="icons">
161160 <xsl:param name="revision"/>
162161 <xsl:if test="$revision/@searched = 'true'">
163 <img src="http://ant.apache.org/ivy/images/searched.gif" alt="searched" title="required a search in repository"/>
162 <img src="https://ant.apache.org/ivy/images/searched.gif" alt="searched" title="required a search in repository"/>
164163 </xsl:if>
165164 <xsl:if test="$revision/@downloaded = 'true'">
166 <img src="http://ant.apache.org/ivy/images/downloaded.gif" alt="downloaded" title="downloaded from repository"/>
165 <img src="https://ant.apache.org/ivy/images/downloaded.gif" alt="downloaded" title="downloaded from repository"/>
167166 </xsl:if>
168167 <xsl:if test="$revision/@evicted">
169168 <xsl:element name="img">
170 <xsl:attribute name="src">http://ant.apache.org/ivy/images/evicted.gif</xsl:attribute>
169 <xsl:attribute name="src">https://ant.apache.org/ivy/images/evicted.gif</xsl:attribute>
171170 <xsl:attribute name="alt">evicted</xsl:attribute>
172171 <xsl:attribute name="title">evicted by <xsl:for-each select="$revision/evicted-by"><xsl:value-of select="@rev"/> </xsl:for-each></xsl:attribute>
173172 </xsl:element>
174173 </xsl:if>
175174 <xsl:if test="$revision/@error">
176175 <xsl:element name="img">
177 <xsl:attribute name="src">http://ant.apache.org/ivy/images/error.gif</xsl:attribute>
176 <xsl:attribute name="src">https://ant.apache.org/ivy/images/error.gif</xsl:attribute>
178177 <xsl:attribute name="alt">error</xsl:attribute>
179178 <xsl:attribute name="title">error: <xsl:value-of select="$revision/@error"/></xsl:attribute>
180179 </xsl:element>
188187 <xsl:param name="error"/>
189188 <tr>
190189 <td>
191 <xsl:element name="a">
192 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/></xsl:attribute>
193 <xsl:value-of select="$module"/>
194 by
195 <xsl:value-of select="$organisation"/>
196 </xsl:element>
190 <xsl:element name="a">
191 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/></xsl:attribute>
192 <xsl:value-of select="$module"/>
193 by
194 <xsl:value-of select="$organisation"/>
195 </xsl:element>
197196 </td>
198197 <td>
199 <xsl:element name="a">
200 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/>-<xsl:value-of select="$revision"/></xsl:attribute>
201 <xsl:value-of select="$revision"/>
202 </xsl:element>
198 <xsl:element name="a">
199 <xsl:attribute name="href">#<xsl:value-of select="$organisation"/>-<xsl:value-of select="$module"/>-<xsl:value-of select="$revision"/></xsl:attribute>
200 <xsl:value-of select="$revision"/>
201 </xsl:element>
203202 </td>
204203 <td>
205 <xsl:value-of select="$error"/>
204 <xsl:value-of select="$error"/>
206205 </td>
207206 </tr>
208207 </xsl:template>
209208
210209 <xsl:template name="confs">
211210 <xsl:param name="configurations"/>
212
211
213212 <xsl:if test="contains($configurations, ',')">
214 <xsl:call-template name="conf">
215 <xsl:with-param name="conf" select="normalize-space(substring-before($configurations,','))"/>
216 </xsl:call-template>
217 <xsl:call-template name="confs">
218 <xsl:with-param name="configurations" select="substring-after($configurations,',')"/>
219 </xsl:call-template>
213 <xsl:call-template name="conf">
214 <xsl:with-param name="conf" select="normalize-space(substring-before($configurations,','))"/>
215 </xsl:call-template>
216 <xsl:call-template name="confs">
217 <xsl:with-param name="configurations" select="substring-after($configurations,',')"/>
218 </xsl:call-template>
220219 </xsl:if>
221220 <xsl:if test="not(contains($configurations, ','))">
222 <xsl:call-template name="conf">
223 <xsl:with-param name="conf" select="normalize-space($configurations)"/>
224 </xsl:call-template>
221 <xsl:call-template name="conf">
222 <xsl:with-param name="conf" select="normalize-space($configurations)"/>
223 </xsl:call-template>
225224 </xsl:if>
226225 </xsl:template>
227226
228227 <xsl:template name="conf">
229228 <xsl:param name="conf"/>
230
229
231230 <li>
232 <xsl:element name="a">
231 <xsl:element name="a">
233232 <xsl:if test="$conf = $myconf">
234 <xsl:attribute name="class">active</xsl:attribute>
233 <xsl:attribute name="class">active</xsl:attribute>
235234 </xsl:if>
236235 <xsl:attribute name="href"><xsl:value-of select="$myorg"/>-<xsl:value-of select="$mymod"/>-<xsl:value-of select="$conf"/>.<xsl:value-of select="$extension"/></xsl:attribute>
237236 <xsl:value-of select="$conf"/>
238 </xsl:element>
237 </xsl:element>
239238 </li>
240239 </xsl:template>
241240
242241 <xsl:template name="date">
243242 <xsl:param name="date"/>
244
243
245244 <xsl:value-of select="substring($date,1,4)"/>-<xsl:value-of select="substring($date,5,2)"/>-<xsl:value-of select="substring($date,7,2)"/>
246245 <xsl:value-of select="' '"/>
247246 <xsl:value-of select="substring($date,9,2)"/>:<xsl:value-of select="substring($date,11,2)"/>:<xsl:value-of select="substring($date,13)"/>
253252 <html>
254253 <head>
255254 <title>Ivy report :: <xsl:value-of select="info/@module"/> by <xsl:value-of select="info/@organisation"/> :: <xsl:value-of select="info/@conf"/></title>
256 <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" />
257 <meta http-equiv="content-language" content="en" />
258 <meta name="robots" content="index,follow" />
259 <link rel="stylesheet" type="text/css" href="ivy-report.css" />
255 <meta http-equiv="content-type" content="text/html; charset=ISO-8859-1"/>
256 <meta http-equiv="content-language" content="en"/>
257 <meta name="robots" content="index,follow"/>
258 <link rel="stylesheet" type="text/css" href="ivy-report.css"/>
260259 </head>
261260 <body>
262 <div id="logo"><a href="http://ant.apache.org/ivy/"><img src="http://ant.apache.org/ivy/images/logo.png"/></a></div>
261 <div id="logo"><a href="https://ant.apache.org/ivy/"><img src="https://ant.apache.org/ivy/images/logo.png"/></a></div>
263262 <h1>
264 <xsl:element name="a">
263 <xsl:element name="a">
265264 <xsl:attribute name="name"><xsl:value-of select="info/@organisation"/>-<xsl:value-of select="info/@module"/></xsl:attribute>
266 </xsl:element>
267 <span id="module">
268 <xsl:value-of select="concat(info/@module, ' ', info/@revision)"/>
269 </span>
270 by
271 <span id="organisation">
272 <xsl:value-of select="info/@organisation"/>
273 </span>
265 </xsl:element>
266 <span id="module">
267 <xsl:value-of select="concat(info/@module, ' ', info/@revision)"/>
268 </span>
269 by
270 <span id="organisation">
271 <xsl:value-of select="info/@organisation"/>
272 </span>
274273 </h1>
275274 <div id="date">
276 resolved on
277 <xsl:call-template name="date">
278 <xsl:with-param name="date" select="info/@date"/>
279 </xsl:call-template>
275 resolved on
276 <xsl:call-template name="date">
277 <xsl:with-param name="date" select="info/@date"/>
278 </xsl:call-template>
280279 </div>
281280 <ul id="confmenu">
282 <xsl:call-template name="confs">
283 <xsl:with-param name="configurations" select="$confs"/>
284 </xsl:call-template>
281 <xsl:call-template name="confs">
282 <xsl:with-param name="configurations" select="$confs"/>
283 </xsl:call-template>
285284 </ul>
286285
287286 <div id="content">
288287 <h2>Dependencies Stats</h2>
289 <table class="header">
290 <tr><td class="title">Modules</td><td class="value"><xsl:value-of select="count($modules)"/></td></tr>
291 <tr><td class="title">Revisions</td><td class="value"><xsl:value-of select="count($revisions)"/>
292 (<xsl:value-of select="count($searcheds)"/> searched <img src="http://ant.apache.org/ivy/images/searched.gif" alt="searched" title="module revisions which required a search with a dependency resolver to be resolved"/>,
293 <xsl:value-of select="count($downloadeds)"/> downloaded <img src="http://ant.apache.org/ivy/images/downloaded.gif" alt="downloaded" title="module revisions for which ivy file was downloaded by dependency resolver"/>,
294 <xsl:value-of select="count($evicteds)"/> evicted <img src="http://ant.apache.org/ivy/images/evicted.gif" alt="evicted" title="module revisions which were evicted by others"/>,
295 <xsl:value-of select="count($errors)"/> errors <img src="http://ant.apache.org/ivy/images/error.gif" alt="error" title="module revisions on which error occurred"/>)</td></tr>
296 <tr><td class="title">Artifacts</td><td class="value"><xsl:value-of select="count($artifacts)"/>
297 (<xsl:value-of select="count($dlartifacts)"/> downloaded,
298 <xsl:value-of select="count($faileds)"/> failed)</td></tr>
299 <tr><td class="title">Artifacts size</td><td class="value"><xsl:value-of select="round(sum($artifacts/@size) div 1024)"/> kB
300 (<xsl:value-of select="round(sum($dlartifacts/@size) div 1024)"/> kB downloaded,
301 <xsl:value-of select="round(sum($cacheartifacts/@size) div 1024)"/> kB in cache)</td></tr>
302 </table>
303
288 <table class="header">
289 <tr><td class="title">Modules</td><td class="value"><xsl:value-of select="count($modules)"/></td></tr>
290 <tr><td class="title">Revisions</td><td class="value"><xsl:value-of select="count($revisions)"/>
291 (<xsl:value-of select="count($searcheds)"/> searched <img src="https://ant.apache.org/ivy/images/searched.gif" alt="searched" title="module revisions which required a search with a dependency resolver to be resolved"/>,
292 <xsl:value-of select="count($downloadeds)"/> downloaded <img src="https://ant.apache.org/ivy/images/downloaded.gif" alt="downloaded" title="module revisions for which ivy file was downloaded by dependency resolver"/>,
293 <xsl:value-of select="count($evicteds)"/> evicted <img src="https://ant.apache.org/ivy/images/evicted.gif" alt="evicted" title="module revisions which were evicted by others"/>,
294 <xsl:value-of select="count($errors)"/> errors <img src="https://ant.apache.org/ivy/images/error.gif" alt="error" title="module revisions on which error occurred"/>)</td></tr>
295 <tr><td class="title">Artifacts</td><td class="value"><xsl:value-of select="count($artifacts)"/>
296 (<xsl:value-of select="count($dlartifacts)"/> downloaded,
297 <xsl:value-of select="count($faileds)"/> failed)</td></tr>
298 <tr><td class="title">Artifacts size</td><td class="value"><xsl:value-of select="round(sum($artifacts/@size) div 1024)"/> kB
299 (<xsl:value-of select="round(sum($dlartifacts/@size) div 1024)"/> kB downloaded,
300 <xsl:value-of select="round(sum($cacheartifacts/@size) div 1024)"/> kB in cache)</td></tr>
301 </table>
302
304303 <xsl:if test="count($errors) > 0">
305304 <h2>Errors</h2>
306305 <table class="errors">
314313 <tbody>
315314 <xsl:for-each select="$errors">
316315 <xsl:call-template name="error">
317 <xsl:with-param name="organisation" select="../@organisation"/>
318 <xsl:with-param name="module" select="../@name"/>
319 <xsl:with-param name="revision" select="@name"/>
320 <xsl:with-param name="error" select="@error"/>
316 <xsl:with-param name="organisation" select="../@organisation"/>
317 <xsl:with-param name="module" select="../@name"/>
318 <xsl:with-param name="revision" select="@name"/>
319 <xsl:with-param name="error" select="@error"/>
321320 </xsl:call-template>
322321 </xsl:for-each>
323322 </tbody>
338337 <xsl:for-each select="$conflicts">
339338 <tr>
340339 <td>
341 <xsl:element name="a">
342 <xsl:attribute name="href">#<xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/></xsl:attribute>
343 <xsl:value-of select="@name"/>
344 by
345 <xsl:value-of select="@organisation"/>
346 </xsl:element>
340 <xsl:element name="a">
341 <xsl:attribute name="href">#<xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/></xsl:attribute>
342 <xsl:value-of select="@name"/>
343 by
344 <xsl:value-of select="@organisation"/>
345 </xsl:element>
347346 </td>
348347 <td>
349 <xsl:for-each select="revision[not(@evicted)]">
350 <xsl:element name="a">
351 <xsl:attribute name="href">#<xsl:value-of select="../@organisation"/>-<xsl:value-of select="../@name"/>-<xsl:value-of select="@name"/></xsl:attribute>
352 <xsl:value-of select="@name"/>
353 </xsl:element>
354 <xsl:text> </xsl:text>
355 </xsl:for-each>
348 <xsl:for-each select="revision[not(@evicted)]">
349 <xsl:element name="a">
350 <xsl:attribute name="href">#<xsl:value-of select="../@organisation"/>-<xsl:value-of select="../@name"/>-<xsl:value-of select="@name"/></xsl:attribute>
351 <xsl:value-of select="@name"/>
352 </xsl:element>
353 <xsl:text> </xsl:text>
354 </xsl:for-each>
356355 </td>
357356 <td>
358 <xsl:for-each select="revision[@evicted]">
359 <xsl:element name="a">
360 <xsl:attribute name="href">#<xsl:value-of select="../@organisation"/>-<xsl:value-of select="../@name"/>-<xsl:value-of select="@name"/></xsl:attribute>
361 <xsl:value-of select="@name"/>
362 <xsl:text> </xsl:text>
363 <xsl:value-of select="@evicted-reason"/>
364 </xsl:element>
365 <xsl:text> </xsl:text>
366 </xsl:for-each>
357 <xsl:for-each select="revision[@evicted]">
358 <xsl:element name="a">
359 <xsl:attribute name="href">#<xsl:value-of select="../@organisation"/>-<xsl:value-of select="../@name"/>-<xsl:value-of select="@name"/></xsl:attribute>
360 <xsl:value-of select="@name"/>
361 <xsl:text> </xsl:text>
362 <xsl:value-of select="@evicted-reason"/>
363 </xsl:element>
364 <xsl:text> </xsl:text>
365 </xsl:for-each>
367366 </td>
368367 </tr>
369368 </xsl:for-each>
378377 <xsl:with-param name="rev" select="info/@revision"/>
379378 </xsl:call-template>
380379
381 <h2>Details</h2>
380 <h2>Details</h2>
382381 <xsl:for-each select="$modules">
383382 <h3>
384383 <xsl:element name="a">
385384 <xsl:attribute name="name"><xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/></xsl:attribute>
386385 </xsl:element>
387386 <xsl:value-of select="@name"/> by <xsl:value-of select="@organisation"/>
388 </h3>
387 </h3>
389388 <xsl:for-each select="revision">
390389 <h4>
391390 <xsl:element name="a">
394393 Revision: <xsl:value-of select="@name"/>
395394 <span style="padding-left:15px;">
396395 <xsl:call-template name="icons">
397 <xsl:with-param name="revision" select="."/>
396 <xsl:with-param name="revision" select="."/>
398397 </xsl:call-template>
399398 </span>
400399 </h4>
401400 <table class="header">
402 <xsl:if test="@homepage">
401 <xsl:if test="@homepage">
403402 <tr><td class="title">Home Page</td><td class="value">
404403 <xsl:element name="a">
405 <xsl:attribute name="href"><xsl:value-of select="@homepage"/></xsl:attribute>
406 <xsl:value-of select="@homepage"/>
407 </xsl:element></td>
408 </tr>
409 </xsl:if>
404 <xsl:attribute name="href"><xsl:value-of select="@homepage"/></xsl:attribute>
405 <xsl:value-of select="@homepage"/>
406 </xsl:element></td>
407 </tr>
408 </xsl:if>
410409 <tr><td class="title">Status</td><td class="value"><xsl:value-of select="@status"/></td></tr>
411410 <tr><td class="title">Publication</td><td class="value"><xsl:value-of select="@pubdate"/></td></tr>
412411 <tr><td class="title">Resolver</td><td class="value"><xsl:value-of select="@resolver"/></td></tr>
413412 <tr><td class="title">Configurations</td><td class="value"><xsl:value-of select="@conf"/></td></tr>
414413 <tr><td class="title">Artifacts size</td><td class="value"><xsl:value-of select="round(sum(artifacts/artifact/@size) div 1024)"/> kB
415 (<xsl:value-of select="round(sum(artifacts/artifact[@status='successful']/@size) div 1024)"/> kB downloaded,
416 <xsl:value-of select="round(sum(artifacts/artifact[@status='no']/@size) div 1024)"/> kB in cache)</td></tr>
417 <xsl:if test="count(license) > 0">
418 <tr><td class="title">Licenses</td><td class="value">
419 <xsl:call-template name="licenses">
420 <xsl:with-param name="revision" select="."/>
421 </xsl:call-template>
422 </td></tr>
423 </xsl:if>
424 <xsl:if test="@evicted">
425 <tr><td class="title">Evicted by</td><td class="value">
426 <b>
427 <xsl:for-each select="evicted-by">
428 <xsl:value-of select="@rev"/>
429 <xsl:text> </xsl:text>
430 </xsl:for-each>
431 </b>
432 <xsl:text> </xsl:text>
433 <b><xsl:value-of select="@evicted-reason"/></b>
434 in <b><xsl:value-of select="@evicted"/></b> conflict manager
435 </td></tr>
436 </xsl:if>
414 (<xsl:value-of select="round(sum(artifacts/artifact[@status='successful']/@size) div 1024)"/> kB downloaded,
415 <xsl:value-of select="round(sum(artifacts/artifact[@status='no']/@size) div 1024)"/> kB in cache)</td></tr>
416 <xsl:if test="count(license) > 0">
417 <tr><td class="title">Licenses</td><td class="value">
418 <xsl:call-template name="licenses">
419 <xsl:with-param name="revision" select="."/>
420 </xsl:call-template>
421 </td></tr>
422 </xsl:if>
423 <xsl:if test="@evicted">
424 <tr><td class="title">Evicted by</td><td class="value">
425 <b>
426 <xsl:for-each select="evicted-by">
427 <xsl:value-of select="@rev"/>
428 <xsl:text> </xsl:text>
429 </xsl:for-each>
430 </b>
431 <xsl:text> </xsl:text>
432 <b><xsl:value-of select="@evicted-reason"/></b>
433 in <b><xsl:value-of select="@evicted"/></b> conflict manager
434 </td></tr>
435 </xsl:if>
437436 </table>
438437 <h5>Required by</h5>
439438 <table>
447446 </tr>
448447 </thead>
449448 <tbody>
450 <xsl:for-each select="caller">
449 <xsl:for-each select="caller">
451450 <tr>
452451 <td><xsl:value-of select="@organisation"/></td>
453452 <td>
454 <xsl:element name="a">
455 <xsl:attribute name="href">#<xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/></xsl:attribute>
456 <xsl:value-of select="@name"/>
457 </xsl:element>
453 <xsl:element name="a">
454 <xsl:attribute name="href">#<xsl:value-of select="@organisation"/>-<xsl:value-of select="@name"/></xsl:attribute>
455 <xsl:value-of select="@name"/>
456 </xsl:element>
458457 </td>
459458 <td><xsl:value-of select="@callerrev"/></td>
460459 <td><xsl:value-of select="@conf"/></td>
461460 <td><xsl:value-of select="@rev"/></td>
462461 </tr>
463 </xsl:for-each>
462 </xsl:for-each>
464463 </tbody>
465464 </table>
466465 <xsl:if test="not(@evicted)">
467
466
468467 <h5>Dependencies</h5>
469468 <xsl:call-template name="calling">
470 <xsl:with-param name="org" select="../@organisation"/>
471 <xsl:with-param name="mod" select="../@name"/>
472 <xsl:with-param name="rev" select="@name"/>
469 <xsl:with-param name="org" select="../@organisation"/>
470 <xsl:with-param name="mod" select="../@name"/>
471 <xsl:with-param name="rev" select="@name"/>
473472 </xsl:call-template>
474473 <h5>Artifacts</h5>
475474 <xsl:if test="count(artifacts/artifact) = 0">
489488 </tr>
490489 </thead>
491490 <tbody>
492 <xsl:for-each select="artifacts/artifact">
491 <xsl:for-each select="artifacts/artifact">
493492 <tr>
494493 <td><xsl:value-of select="@name"/></td>
495494 <td><xsl:value-of select="@type"/></td>
497496 <td align="center"><xsl:value-of select="@status"/></td>
498497 <td align="center"><xsl:value-of select="round(number(@size) div 1024)"/> kB</td>
499498 </tr>
500 </xsl:for-each>
499 </xsl:for-each>
501500 </tbody>
502501 </table>
503502 </xsl:if>
504
503
505504 </xsl:if>
506 </xsl:for-each>
505 </xsl:for-each>
507506 </xsl:for-each>
508507 </div>
509508 </body>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import javax.swing.event.EventListenerList;
2424
2525 import org.apache.ivy.core.module.descriptor.Artifact;
26 import org.apache.ivy.core.settings.TimeoutConstraint;
2627
2728 public abstract class AbstractRepository implements Repository {
2829 private EventListenerList listeners = new EventListenerList();
3031 private String name;
3132
3233 private TransferEvent evt;
34
35 private final TimeoutConstraint timeoutConstraint;
36
37 public AbstractRepository() {
38 this(null);
39 }
40
41 protected AbstractRepository(final TimeoutConstraint timeoutConstraint) {
42 this.timeoutConstraint = timeoutConstraint;
43 }
3344
3445 public void addTransferListener(TransferListener listener) {
3546 listeners.add(TransferListener.class, listener);
120131 this.name = name;
121132 }
122133
134 public TimeoutConstraint getTimeoutConstraint() {
135 return this.timeoutConstraint;
136 }
137
138 @Override
123139 public String toString() {
124140 return getName();
125141 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 * {@link ResolvedResource}.
2525 */
2626 public interface ArtifactResourceResolver {
27 public ResolvedResource resolve(Artifact artifact);
27 ResolvedResource resolve(Artifact artifact);
2828 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232 * @throws IllegalStateException
3333 * when {@link #isLocal()} returns <code>false</code>
3434 */
35 public File getFile();
35 File getFile();
3636
3737 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 /**
2626 * Represents a collection of resources available to Ivy. Ivy uses one or more repositories as both
2727 * a source of resources for Ivy enabled build systems and as a distribution center for resources
28 * generated by Ivy enabled build systems. </p>
29 * <p>
30 * A repository supports the following fundamental operations
28 * generated by Ivy enabled build systems.
29 * <p>A repository supports the following fundamental operations</p>
3130 * <ul>
3231 * <li>retrieving a resource from the repository.</li>
3332 * <li>transferring a resource to the repository.</li>
3433 * <li>retrieving a listing of resources.</li>
3534 * </ul>
36 * </p>
37 * <h4>Resource Retrieval</h4> </p>
38 * <p>
39 * {@link #get} retrieves a resource specified by a provided identifier creating a new file .
40 * </p>
41 * </p> <h4>resource Publication</h4> </p>
42 * <p>
43 * {@link #put} transfers a file to the repository.
44 * </p>
45 * </p> <h4>resource Listing</h4> </p>
35 * <h3>Resource Retrieval</h3>
36 * <p>{@link #get} retrieves a resource specified by a provided identifier creating a new file.</p>
37 * <h3>Resource Publication</h3>
38 * <p>{@link #put} transfers a file to the repository.</p>
39 * <h2>resource Listing</h2>
4640 * <p>
4741 * {@link #list} returns a listing of file like objects belonging to a specified parent directory.
48 * </p>
4942 * </p>
5043 */
5144 public interface Repository {
5447 * Return the resource associated with a specified identifier. If the resource does not exist,
5548 * it should return a Resource with exists() returning false. An IOException should only be
5649 * thrown when a real IO problem occurs, like the impossibility to connect to a server.
57 *
50 *
5851 * @param source
5952 * A string identifying the resource.
6053 * @return The resource associated with the resource identifier.
6558
6659 /**
6760 * Fetch a resource from the repository.
68 *
61 *
6962 * @param source
7063 * A string identifying the resource to be fetched.
7164 * @param destination
7770
7871 /**
7972 * Transfer a resource to the repository
80 *
73 *
8174 * @param artifact
8275 * The artifact to be transferred.
8376 * @param source
9487
9588 /**
9689 * Return a listing of resources names
97 *
90 *
9891 * @param parent
9992 * The parent directory from which to generate the listing.
100 * @return A listing of the parent directory's file content, as a List of String.
93 * @return A listing of the parent directory's file content
10194 * @throws IOException
10295 * On listing failure.
10396 */
104 List list(String parent) throws IOException;
97 List<String> list(String parent) throws IOException;
10598
10699 /**
107100 * Add a listener to the repository.
108 *
101 *
109102 * @param listener
110103 * The listener to attach to the repository.
111104 */
113106
114107 /**
115108 * Remove a listener on the repository
116 *
109 *
117110 * @param listener
118111 * The listener to remove
119112 */
121114
122115 /**
123116 * Determine if a given listener is attached to the repository.
124 *
117 *
125118 * @param listener
126119 * The listener being queried
127120 * @return <code>true</code> if the provided listener is attached to the repository,
131124
132125 /**
133126 * Get the repository's file separator string.
134 *
127 *
135128 * @return The repository's file separator delimiter
136129 */
137130 String getFileSeparator();
138131
139132 /**
140133 * Normalize a string.
141 *
134 *
142135 * @param source
143136 * The string to normalize.
144137 * @return The normalized string.
147140
148141 /**
149142 * Return the name of the repository
143 *
144 * @return String name
150145 */
151146 String getName();
152147 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 private Long totalLength = null;
3030
3131 public void start(CopyProgressEvent evt) {
32 if (totalLength != null) {
33 repository.fireTransferStarted(totalLength.longValue());
32 if (totalLength == null) {
33 repository.fireTransferStarted();
3434 } else {
35 repository.fireTransferStarted();
35 repository.fireTransferStarted(totalLength);
3636 }
3737 }
3838
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 * <li>size of the resource in bytes.</li>
2929 * <li>if the resource is available.</li>
3030 * </ul>
31 * </p> <h4>Implementation Notes</h4> In implementing the interface you need to ensure the following
32 * behaviors:
31 * <h3>Implementation Notes</h3>
32 * In implementing the interface you need to ensure the following behaviors:
3333 * <ul>
34 * <li>All of the methods specified in the interface fail by returning an empty value (
35 * <code>false</code>, <code>0</code>, <code>""</code>). In other words, the specified interface
34 * <li>All of the methods specified in the interface fail by returning an empty value
35 * (<code>false</code>, <code>0</code>, <code>""</code>). In other words, the specified interface
3636 * methods should not throw RuntimeExceptions.</li>
3737 * <li>Failure conditions should be logged using the {@link org.apache.ivy.util.Message#verbose}
3838 * method.</li>
3939 * <li>Failure of one of the interface's specified methods results in all other interface specified
4040 * methods returning an empty value (<code>false</code>, <code>0</code>, <code>""</code>).</li>
4141 * </ul>
42 * </p>
4342 */
4443
4544 public interface Resource {
4645 /**
4746 * Get the name of the resource.
48 *
49 * @return the repositorie's assigned resource name/identifier.
47 *
48 * @return the repository's assigned resource name/identifier.
5049 */
51 public String getName();
50 String getName();
5251
5352 /**
5453 * Get the date the resource was last modified
55 *
54 *
5655 * @return A <code>long</code> value representing the time the file was last modified, measured
5756 * in milliseconds since the epoch (00:00:00 GMT, January 1, 1970), or <code>0L</code>
5857 * if the file does not exist or if an I/O error occurs.
5958 */
60 public long getLastModified();
59 long getLastModified();
6160
6261 /**
6362 * Get the resource size
64 *
63 *
6564 * @return a <code>long</code> value representing the size of the resource in bytes.
6665 */
67 public long getContentLength();
66 long getContentLength();
6867
6968 /**
70 * Determine if the resource is available. </p> Note that this method only checks for
69 * Determine if the resource is available. Note that this method only checks for
7170 * availability, not for actual existence.
72 *
71 *
7372 * @return <code>boolean</code> value indicating if the resource is available.
7473 */
75 public boolean exists();
74 boolean exists();
7675
7776 /**
7877 * Is this resource local to this host, i.e. is it on the file system?
79 *
78 *
8079 * @return <code>boolean</code> value indicating if the resource is local.
8180 */
82 public boolean isLocal();
81 boolean isLocal();
8382
8483 /**
8584 * Clones this resource with a new resource with a different name
86 *
85 *
8786 * @param cloneName
8887 * the name of the clone
8988 * @return the cloned resource
9089 */
91 public Resource clone(String cloneName);
90 Resource clone(String cloneName);
9291
9392 /**
9493 * Opens a stream on this resource
95 *
94 *
9695 * @return the opened input stream
96 * @throws IOException if something goes wrong
9797 */
98 public InputStream openStream() throws IOException;
98 InputStream openStream() throws IOException;
9999 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3333 * </p>
3434 */
3535 public interface ResourceDownloader {
36 public void download(Artifact artifact, Resource resource, File dest) throws IOException;
36 void download(Artifact artifact, Resource resource, File dest) throws IOException;
3737 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222
2323 /**
2424 * TransferEvent is used to notify TransferListeners about progress in transfer of resources form/to
25 * the respository This class is LARGELY inspired by org.apache.maven.wagon.events.TransferEvent
25 * the repository This class is LARGELY inspired by org.apache.maven.wagon.events.TransferEvent
2626 * released under the following copyright license:
27 *
27 *
2828 * <pre>
29 *
29 *
3030 * Copyright 2001-2005 The Apache Software Foundation.
31 *
31 *
3232 * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);
3333 * you may not use this file except in compliance with the License.
3434 * You may obtain a copy of the License at
35 *
36 * http://www.apache.org/licenses/LICENSE-2.0
37 *
35 *
36 * https://www.apache.org/licenses/LICENSE-2.0
37 *
3838 * Unless required by applicable law or agreed to in writing, software
3939 * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,
4040 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4141 * See the License for the specific language governing permissions and
4242 * limitations under the License.
43 *
43 *
4444 * </pre>
45 *
46 * Orginal class written by Michal Maczka.
45 *
46 * Original class written by Michal Maczka.
4747 */
4848 public class TransferEvent extends IvyEvent {
4949 /**
183183
184184 /**
185185 * Returns the request type.
186 *
186 *
187187 * @return Returns the request type. The Request type is one of
188 * <code>TransferEvent.REQUEST_GET<code> or <code>TransferEvent.REQUEST_PUT<code>
188 * TransferEvent.REQUEST_GET or TransferEvent.REQUEST_PUT
189189 */
190190 public int getRequestType() {
191191 return requestType;
193193
194194 /**
195195 * Sets the request type
196 *
196 *
197197 * @param requestType
198198 * The requestType to set. The Request type value should be either
199 * <code>TransferEvent.REQUEST_GET<code> or <code>TransferEvent.REQUEST_PUT<code>.
199 * TransferEvent.REQUEST_GET or TransferEvent.REQUEST_PUT
200200 * @throws IllegalArgumentException
201201 * when
202202 */
203203 protected void setRequestType(final int requestType) {
204204 switch (requestType) {
205
206205 case REQUEST_PUT:
207 break;
208206 case REQUEST_GET:
209207 break;
210
211208 default:
212209 throw new IllegalArgumentException("Illegal request type: " + requestType);
213210 }
302299 /**
303300 * Returns the elapsed time (in ms) between when the event entered one type until it entered
304301 * another event time.
305 * <p>
306 * This is especially useful to get the elapsed transfer time:
307 *
302 * <p>This is especially useful to get the elapsed transfer time:</p>
308303 * <pre>
309304 * getElapsedTime(TransferEvent.TRANSFER_STARTED, TransferEvent.TRANSFER_COMPLETED);
310305 * </pre>
311 *
312 * </p>
313 * <p>
314 * Special cases:
306 * <p>Special cases:</p>
315307 * <ul>
316308 * <li>returns -1 if the event never entered the fromEventType or the toEventType.</li>
317309 * <li>returns 0 if the event entered toEventType before fromEventType</li>
318310 * </ul>
319 * </p>
320 *
311 *
321312 * @param fromEventType
322313 * the event type constant from which time should be measured
323314 * @param toEventType
344335 /**
345336 * Checks the given event type is a valid event type, throws an {@link IllegalArgumentException}
346337 * if it isn't
347 *
338 *
348339 * @param eventType
349340 * the event type to check
350341 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
7171
7272 private void copy(File src, File destination, boolean overwrite) throws IOException {
7373 try {
74 getProgressListener().setTotalLength(new Long(src.length()));
74 getProgressListener().setTotalLength(src.length());
7575 if (!FileUtil.copy(src, destination, getProgressListener(), overwrite)) {
7676 if (!overwrite && destination.exists()) {
7777 throw new IOException("file copy not done from " + src + " to " + destination
8080 throw new IOException("file copy not done from " + src + " to " + destination);
8181 }
8282 }
83 } catch (IOException ex) {
84 fireTransferError(ex);
85 throw ex;
86 } catch (RuntimeException ex) {
83 } catch (IOException | RuntimeException ex) {
8784 fireTransferError(ex);
8885 throw ex;
8986 } finally {
9592 return progress;
9693 }
9794
98 public List list(String parent) throws IOException {
95 public List<String> list(String parent) throws IOException {
9996 File dir = getFile(parent);
10097 if (dir.exists() && dir.isDirectory()) {
10198 String[] names = dir.list();
10299 if (names != null) {
103 List ret = new ArrayList(names.length);
104 for (int i = 0; i < names.length; i++) {
105 ret.add(parent + getFileSeparator() + names[i]);
100 List<String> ret = new ArrayList<>(names.length);
101 for (String name : names) {
102 ret.add(parent + getFileSeparator() + name);
106103 }
107104 return ret;
108105 }
111108 }
112109
113110 File getFile(String source) {
114 if (baseDir != null) {
115 return FileUtil.resolveFile(baseDir, source);
116 } else {
111 if (baseDir == null) {
117112 return Checks.checkAbsolute(source, "source");
118113 }
114 return FileUtil.resolveFile(baseDir, source);
119115 }
120116
121117 public boolean isLocal() {
136132 }
137133
138134 public String standardize(String source) {
139 if (baseDir != null) {
140 return FileUtil.resolveFile(baseDir, source).getPath();
141 } else {
135 if (baseDir == null) {
142136 return FileUtil.normalize(source).getPath();
143137 }
138 return FileUtil.resolveFile(baseDir, source).getPath();
144139 }
145140
146141 public String getFileSeparator() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.util.ArrayList;
2323 import java.util.Enumeration;
2424 import java.util.List;
25 import java.util.jar.JarEntry;
2526 import java.util.jar.JarFile;
2627 import java.util.zip.ZipEntry;
2728
29 import org.apache.ivy.core.settings.TimeoutConstraint;
2830 import org.apache.ivy.plugins.repository.AbstractRepository;
2931 import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
3032 import org.apache.ivy.plugins.repository.Resource;
3638 private RepositoryCopyProgressListener progress = new RepositoryCopyProgressListener(this);
3739
3840 private JarFile jarFile;
41
42 public JarRepository() {
43
44 }
45
46 public JarRepository(final TimeoutConstraint timeoutConstraint) {
47 super(timeoutConstraint);
48 }
3949
4050 public void setJarFile(JarFile jarFile) {
4151 this.jarFile = jarFile;
5666 if (entry == null) {
5767 throw new FileNotFoundException();
5868 }
59 getProgressListener().setTotalLength(new Long(entry.getSize()));
69 getProgressListener().setTotalLength(entry.getSize());
6070 FileUtil.copy(jarFile.getInputStream(entry), destination, getProgressListener());
61 } catch (IOException ex) {
62 fireTransferError(ex);
63 throw ex;
64 } catch (RuntimeException ex) {
71 } catch (IOException | RuntimeException ex) {
6572 fireTransferError(ex);
6673 throw ex;
6774 } finally {
6976 }
7077 }
7178
72 public List/* <String> */list(String parent) throws IOException {
79 public List<String> list(String parent) throws IOException {
7380 ZipEntry parentEntry = jarFile.getEntry(parent);
7481 if (parentEntry == null || !parentEntry.isDirectory()) {
7582 return null;
7683 }
77 List/* <String> */children = new ArrayList();
78 Enumeration entries = jarFile.entries();
84 List<String> children = new ArrayList<>();
85 Enumeration<JarEntry> entries = jarFile.entries();
7986 while (entries.hasMoreElements()) {
80 ZipEntry entry = (ZipEntry) entries.nextElement();
81 if (entry.getName().startsWith(parent) && entry.getName().equals(parentEntry.getName())) {
87 JarEntry entry = entries.nextElement();
88 if (entry.getName().startsWith(parent)
89 && entry.getName().equals(parentEntry.getName())) {
8290 children.add(entry.getName());
8391 }
8492 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.net.URISyntaxException;
2424 import java.util.ArrayList;
2525 import java.util.Collection;
26 import java.util.Iterator;
2726 import java.util.List;
2827
28 import org.apache.ivy.core.settings.TimeoutConstraint;
2929 import org.apache.ivy.plugins.repository.BasicResource;
3030 import org.apache.ivy.plugins.repository.Resource;
3131 import org.apache.ivy.plugins.repository.TransferEvent;
7272 public SFTPRepository() {
7373 }
7474
75 public SFTPRepository(final TimeoutConstraint timeoutConstraint) {
76 super(timeoutConstraint);
77 }
78
7579 public Resource getResource(String source) {
7680 return new SFTPResource(this, source);
7781 }
7983 /**
8084 * This method is similar to getResource, except that the returned resource is fully initialized
8185 * (resolved in the sftp repository), and that the given string is a full remote path
82 *
86 *
8387 * @param path
8488 * the full remote path in the repository of the resource
8589 * @return a fully initialized resource, able to answer to all its methods without needing any
8690 * further connection
8791 */
92 @SuppressWarnings("unchecked")
8893 public Resource resolveResource(String path) {
8994 try {
90 ChannelSftp c = getSftpChannel(path);
91
92 Collection r = c.ls(getPath(path));
93
95 List<LsEntry> r = getSftpChannel(path).ls(getPath(path));
9496 if (r != null) {
95 for (Iterator iter = r.iterator(); iter.hasNext();) {
96 Object obj = iter.next();
97 if (obj instanceof LsEntry) {
98 LsEntry entry = (LsEntry) obj;
99 SftpATTRS attrs = entry.getAttrs();
100 return new BasicResource(path, true, attrs.getSize(), attrs.getMTime()
101 * MILLIS_PER_SECOND, false);
102 }
103 }
97 SftpATTRS attrs = r.get(0).getAttrs();
98 return new BasicResource(path, true, attrs.getSize(),
99 attrs.getMTime() * MILLIS_PER_SECOND, false);
104100 }
105101 } catch (Exception e) {
106102 Message.debug("Error while resolving resource " + path, e);
107 // silent fail, return unexisting resource
103 // silent fail, return nonexistent resource
108104 }
109105
110106 return new BasicResource(path, false, 0, 0, false);
115111 try {
116112 String path = getPath(resource.getName());
117113 return c.get(path);
118 } catch (SftpException e) {
119 IOException ex = new IOException("impossible to open stream for " + resource + " on "
120 + getHost() + (e.getMessage() != null ? ": " + e.getMessage() : ""));
121 ex.initCause(e);
122 throw ex;
123 } catch (URISyntaxException e) {
124 IOException ex = new IOException("impossible to open stream for " + resource + " on "
125 + getHost() + (e.getMessage() != null ? ": " + e.getMessage() : ""));
126 ex.initCause(e);
127 throw ex;
114 } catch (SftpException | URISyntaxException e) {
115 throw new IOException("impossible to open stream for " + resource + " on "
116 + getHost() + (e.getMessage() != null ? ": " + e.getMessage() : ""), e);
128117 }
129118 }
130119
134123 try {
135124 String path = getPath(source);
136125 c.get(path, destination.getAbsolutePath(), new MyProgressMonitor());
137 } catch (SftpException e) {
138 IOException ex = new IOException("impossible to get " + source + " on " + getHost()
139 + (e.getMessage() != null ? ": " + e.getMessage() : ""));
140 ex.initCause(e);
141 throw ex;
142 } catch (URISyntaxException e) {
143 IOException ex = new IOException("impossible to get " + source + " on " + getHost()
144 + (e.getMessage() != null ? ": " + e.getMessage() : ""));
145 ex.initCause(e);
146 throw ex;
126 } catch (SftpException | URISyntaxException e) {
127 throw new IOException("impossible to get " + source + " on " + getHost()
128 + (e.getMessage() != null ? ": " + e.getMessage() : ""), e);
147129 }
148130 }
149131
159141 mkdirs(path.substring(0, path.lastIndexOf('/')), c);
160142 }
161143 c.put(source.getAbsolutePath(), path, new MyProgressMonitor());
162 } catch (SftpException e) {
163 IOException ex = new IOException(e.getMessage());
164 ex.initCause(e);
165 throw ex;
166 } catch (URISyntaxException e) {
167 IOException ex = new IOException(e.getMessage());
168 ex.initCause(e);
169 throw ex;
170 }
171 }
172
173 private void mkdirs(String directory, ChannelSftp c) throws IOException, SftpException {
144 } catch (SftpException | URISyntaxException e) {
145 throw new IOException(e.getMessage(), e);
146 }
147 }
148
149 private void mkdirs(String directory, ChannelSftp c) throws SftpException {
174150 try {
175151 SftpATTRS att = c.stat(directory);
176 if (att != null) {
177 if (att.isDir()) {
178 return;
179 }
152 if (att != null && att.isDir()) {
153 return;
180154 }
181155 } catch (SftpException ex) {
182156 if (directory.indexOf('/') != -1) {
198172 return result;
199173 }
200174
201 public List list(String parent) throws IOException {
175 @SuppressWarnings("unchecked")
176 public List<String> list(String parent) throws IOException {
202177 try {
203178 ChannelSftp c = getSftpChannel(parent);
204179 String path = getPath(parent);
205 Collection r = c.ls(path);
180 Collection<LsEntry> r = c.ls(path);
206181 if (r != null) {
207182 if (!path.endsWith("/")) {
208183 path = parent + "/";
209184 }
210 List result = new ArrayList();
211 for (Iterator iter = r.iterator(); iter.hasNext();) {
212 Object obj = iter.next();
213 if (obj instanceof LsEntry) {
214 LsEntry entry = (LsEntry) obj;
215 if (".".equals(entry.getFilename()) || "..".equals(entry.getFilename())) {
216 continue;
217 }
218 result.add(path + entry.getFilename());
185 List<String> result = new ArrayList<>();
186 for (LsEntry entry : r) {
187 if (".".equals(entry.getFilename()) || "..".equals(entry.getFilename())) {
188 continue;
219189 }
190 result.add(path + entry.getFilename());
220191 }
221192 return result;
222193 }
223 } catch (SftpException e) {
224 IOException ex = new IOException("Failed to return a listing for '" + parent + "'");
225 ex.initCause(e);
226 throw ex;
227 } catch (URISyntaxException usex) {
228 IOException ex = new IOException("Failed to return a listing for '" + parent + "'");
229 ex.initCause(usex);
230 throw ex;
194 } catch (SftpException | URISyntaxException e) {
195 throw new IOException("Failed to return a listing for '" + parent + "'", e);
231196 }
232197 return null;
233198 }
234199
235200 /**
236201 * Checks the existence for a remote file
237 *
202 *
238203 * @param file
239204 * to check
240205 * @param channel
241206 * to use
242 * @returns true if file exists, false otherwise
243 * @throws IOException
244 * @throws SftpException
207 * @return true if file exists, false otherwise
245208 */
246 private boolean checkExistence(String file, ChannelSftp channel) throws IOException,
247 SftpException {
209 private boolean checkExistence(String file, ChannelSftp channel) {
248210 try {
249211 return channel.stat(file) != null;
250212 } catch (SftpException ex) {
256218 * Establish the connection to the server if not yet connected, and listen to ivy events for
257219 * closing connection when resolve is finished. Not meant to be used in multi threaded
258220 * environment.
259 *
221 *
260222 * @return the ChannelSftp with which a connection is established
261223 * @throws IOException
262224 * if any connection problem occurs
272234 Message.verbose(":: SFTP :: connected to " + host + "!");
273235 SshCache.getInstance().attachChannelSftp(session, channel);
274236 } catch (JSchException e) {
275 IOException ex = new IOException(e.getMessage());
276 ex.initCause(e);
277 throw ex;
237 throw new IOException(e.getMessage(), e);
278238 }
279239 }
280240 return channel;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.net.URISyntaxException;
2323 import java.util.HashMap;
2424 import java.util.Locale;
25
25 import java.util.Map;
26
27 import org.apache.ivy.core.settings.TimeoutConstraint;
2628 import org.apache.ivy.plugins.repository.AbstractRepository;
2729 import org.apache.ivy.util.Credentials;
2830 import org.apache.ivy.util.CredentialsUtil;
2931 import org.apache.ivy.util.Message;
3032
33 import com.jcraft.jsch.ConfigRepository;
34 import com.jcraft.jsch.ConfigRepository.Config;
35 import com.jcraft.jsch.OpenSSHConfig;
3136 import com.jcraft.jsch.Session;
3237
3338 public abstract class AbstractSshBasedRepository extends AbstractRepository {
4752 private int port = -1;
4853
4954 private boolean allowedAgentUse = false;
55
56 private String sshConfig = null;
5057
5158 public AbstractSshBasedRepository() {
5259 super();
5360 }
5461
62 public AbstractSshBasedRepository(final TimeoutConstraint timeoutConstraint) {
63 super(timeoutConstraint);
64 }
65
5566 /**
5667 * hashmap of user/hosts with credentials. key is hostname, value is Credentials
5768 **/
58 private static HashMap credentialsCache = new HashMap();
59
60 private static final int MAX_CREDENTILAS_CACHE_SIZE = 100;
69 private static final Map<String, Credentials> credentialsCache = new HashMap<>();
70
71 private static final int MAX_CREDENTIALS_CACHE_SIZE = 100;
6172
6273 /**
6374 * get a new session using the default attributes if the given String is a full uri, use the
6475 * data from the uri instead
65 *
76 *
6677 * @param pathOrUri
6778 * might be just a path or a full ssh or sftp uri
6879 * @return matching Session
80 * @throws IOException if something goes wrong
6981 */
7082 protected Session getSession(String pathOrUri) throws IOException {
7183 URI uri = parseURI(pathOrUri);
7385 int port = getPort();
7486 String user = getUser();
7587 String userPassword = getUserPassword();
88 String sshConfig = getSshConfig();
89 File keyFile = getKeyFile();
7690 if (uri != null && uri.getScheme() != null) {
7791 if (uri.getHost() != null) {
7892 host = uri.getHost();
8296 }
8397 if (uri.getUserInfo() != null) {
8498 String userInfo = uri.getUserInfo();
85 if (userInfo.indexOf(":") == -1) {
99 if (!userInfo.contains(":")) {
86100 user = userInfo;
87101 } else {
88102 user = userInfo.substring(0, userInfo.indexOf(":"));
90104 }
91105 }
92106 }
107
108 if (sshConfig != null) {
109 ConfigRepository configRepository = OpenSSHConfig.parseFile(sshConfig);
110 Config config = configRepository.getConfig(host);
111 host = config.getHostname();
112 if (user == null) {
113 user = config.getUser();
114 }
115 String keyFilePath = config.getValue("IdentityFile");
116 if (keyFilePath != null && keyFile == null) {
117 keyFile = new File(keyFilePath);
118 }
119 }
120
93121 if (host == null) {
94122 throw new IllegalArgumentException(
95123 "missing host information. host should be provided either "
96 + "directly on the repository or in the connection URI");
124 + "directly on the repository or in the connection URI "
125 + ", or in the openssh config file specified by sshConfig");
97126 }
98127 if (user == null) {
99128 Credentials c = requestCredentials(host);
104133 Message.error("username is not set");
105134 }
106135 }
107 return SshCache.getInstance().getSession(host, port, user, userPassword, getKeyFile(),
136 return SshCache.getInstance().getSession(host, port, user, userPassword, keyFile,
108137 getKeyFilePassword(), getPassFile(), isAllowedAgentUse());
109138 }
110139
111140 /**
112141 * Just check the uri for sanity
113 *
142 *
114143 * @param source
115144 * String of the uri
116145 * @return URI object of the String or null
144173 }
145174
146175 /**
147 * Called, when user was not found in URL. Maintain static hashe of credentials and retrieve or
176 * Called, when user was not found in URL. Maintain static hash of credentials and retrieve or
148177 * ask credentials for host.
149 *
178 *
150179 * @param host
151180 * host for which we want to get credentials.
152181 * @return credentials for given host
153182 **/
154183 private Credentials requestCredentials(String host) {
155 Object o = credentialsCache.get(host);
156 if (o == null) {
157 Credentials c = CredentialsUtil.promptCredentials(new Credentials(null, host, user,
184 Credentials c = credentialsCache.get(host);
185 if (c == null) {
186 c = CredentialsUtil.promptCredentials(new Credentials(null, host, user,
158187 userPassword), getPassFile());
159188 if (c != null) {
160 if (credentialsCache.size() > MAX_CREDENTILAS_CACHE_SIZE) {
189 if (credentialsCache.size() > MAX_CREDENTIALS_CACHE_SIZE) {
161190 credentialsCache.clear();
162191 }
163192 credentialsCache.put(host, c);
164193 }
165 return c;
166 } else {
167 return (Credentials) o;
168 }
194 }
195 return c;
169196 }
170197
171198 /**
172199 * closes the session and remove it from the cache (eg. on case of errors)
173 *
200 *
174201 * @param session
175202 * key for the cache
176203 * @param pathOrUri
183210
184211 /**
185212 * set the default user to use for the connection if no user is given or a PEM file is used
186 *
213 *
187214 * @param user
188215 * to use
189216 */
200227
201228 /**
202229 * Sets the full file path to use for accessing a PEM key file
203 *
230 *
204231 * @param filePath
205232 * fully qualified name
206233 */
314341 this.allowedAgentUse = allowedAgentUse;
315342 }
316343
344 /**
345 * @return sshConfig Path to a local ssh config file
346 */
347 public String getSshConfig() {
348 return sshConfig;
349 }
350
351 /**
352 * @param sshConfig
353 * Path to a local ssh config file
354 */
355 public void setSshConfig(String sshConfig) {
356 this.sshConfig = sshConfig;
357 }
358
317359 protected abstract String getRepositoryScheme();
318360
319361 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 /**
2020 * This exception will be used for Remote SCP Exceptions (failures on the target system, no
21 * connetion probs)
21 * connection probs)
2222 */
2323 public class RemoteScpException extends Exception {
2424
2828 }
2929
3030 /**
31 * @param message
31 * @param message ditto
3232 */
3333 public RemoteScpException(String message) {
3434 super(message);
3535 }
3636
3737 /**
38 * @param cause
38 * @param cause Throwable
3939 */
4040 public RemoteScpException(Throwable cause) {
4141 super(cause);
4242 }
4343
4444 /**
45 * @param message
46 * @param cause
45 * @param message ditto
46 * @param cause Throwable
4747 */
4848 public RemoteScpException(String message, Throwable cause) {
4949 super(message, cause);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
140140 throw new RemoteScpException("Remote scp terminated unexpectedly.");
141141 }
142142
143 if ((c != 1) && (c != 2)) {
143 if (c != 1 && c != 2) {
144144 throw new RemoteScpException("Remote scp sent illegal error code.");
145145 }
146146
153153 }
154154
155155 private String receiveLine(InputStream is) throws IOException, RemoteScpException {
156 StringBuffer sb = new StringBuffer(DEFAULT_LINE_BUFFER_LENGTH);
156 StringBuilder sb = new StringBuilder(DEFAULT_LINE_BUFFER_LENGTH);
157157
158158 while (true) {
159159
187187 "Malformed C line sent by remote SCP binary, line too short.");
188188 }
189189
190 if ((line.charAt(CLINE_SPACE_INDEX1) != ' ') || (line.charAt(CLINE_SPACE_INDEX2) == ' ')) {
190 if (line.charAt(CLINE_SPACE_INDEX1) != ' ' || line.charAt(CLINE_SPACE_INDEX2) == ' ') {
191191 throw new RemoteScpException("Malformed C line sent by remote SCP binary.");
192192 }
193193
200200 String lengthSubstring = line.substring(CLINE_SPACE_INDEX2, lengthNameSep);
201201 String nameSubstring = line.substring(lengthNameSep + 1);
202202
203 if ((lengthSubstring.length() <= 0) || (nameSubstring.length() <= 0)) {
203 if (lengthSubstring.length() <= 0 || nameSubstring.length() <= 0) {
204204 throw new RemoteScpException("Malformed C line sent by remote SCP binary.");
205205 }
206206
207 if ((CLINE_SPACE_INDEX2 + 1 + lengthSubstring.length() + nameSubstring.length()) != line
207 if (CLINE_SPACE_INDEX2 + 1 + lengthSubstring.length() + nameSubstring.length() != line
208208 .length()) {
209209 throw new RemoteScpException("Malformed C line sent by remote SCP binary.");
210210 }
288288 } else {
289289 channel.connect();
290290 }
291 } catch (JSchException e1) {
292 throw (IOException) new IOException("Channel connection problems").initCause(e1);
291 } catch (JSchException jsche) {
292 throw new IOException("Channel connection problems", jsche);
293293 }
294294
295295 readResponse(is);
308308
309309 readResponse(is);
310310
311 FileInputStream fis = null;
312
313 try {
314 fis = new FileInputStream(f);
315
311 try (FileInputStream fis = new FileInputStream(f)) {
316312 while (remain > 0) {
317313 int trans;
318314 if (remain > buffer.length) {
328324
329325 remain -= trans;
330326 }
331
332 fis.close();
333 } catch (IOException e) {
334 if (fis != null) {
335 fis.close();
336 }
337 throw (e);
338327 }
339328
340329 os.write(0);
348337
349338 /**
350339 * Receive a file via scp and store it in a stream
351 *
340 *
352341 * @param channel
353342 * ssh channel to use
354343 * @param file
355344 * to receive from remote
356 * @param target
345 * @param targetStream
357346 * to store file into (if null, get only file info)
358347 * @return file information of the file we received
359348 * @throws IOException
373362 } else {
374363 channel.connect();
375364 }
376 } catch (JSchException e1) {
377 throw (IOException) new IOException("Channel connection problems").initCause(e1);
365 } catch (JSchException jsche) {
366 throw new IOException("Channel connection problems", jsche);
378367 }
379368 os.write(0x0);
380369 os.flush();
395384 os.flush();
396385 continue;
397386 }
398 if ((c == 1) || (c == 2)) {
387 if (c == 1 || c == 2) {
399388 throw new RemoteScpException("Remote SCP error: " + line);
400389 }
401390
449438 }
450439
451440 /**
452 * @return
453 * @throws JSchException
441 * @return ChannelExec
442 * @throws JSchException if something goes wrong
454443 */
455444 private ChannelExec getExecChannel() throws JSchException {
456445 ChannelExec channel;
461450 /**
462451 * Copy a local file to a remote site, uses the specified mode when creating the file on the
463452 * remote side.
464 *
453 *
465454 * @param localFile
466455 * Path and name of local file. Must be absolute.
467456 * @param remoteTargetDir
475464 * @throws RemoteScpException
476465 * in case of problems on the target system (connection ok)
477466 */
467 @SuppressWarnings("unused")
478468 public void put(String localFile, String remoteTargetDir, String remoteTargetName, String mode)
479469 throws IOException, RemoteScpException {
480470 ChannelExec channel = null;
481471
482 if ((localFile == null) || (remoteTargetName == null)) {
472 if (localFile == null || remoteTargetName == null) {
483473 throw new IllegalArgumentException("Null argument.");
484474 }
485475
488478 throw new IllegalArgumentException("Invalid mode.");
489479 }
490480
491 for (int i = 0; i < mode.length(); i++) {
492 if (!Character.isDigit(mode.charAt(i))) {
481 for (char c : mode.toCharArray()) {
482 if (!Character.isDigit(c)) {
493483 throw new IllegalArgumentException("Invalid mode.");
494484 }
495485 }
497487
498488 String cmd = "scp -t ";
499489 if (mode != null) {
500 cmd = cmd + "-p ";
490 cmd += "-p ";
501491 }
502492 if (remoteTargetDir != null && remoteTargetDir.length() > 0) {
503 cmd = cmd + "-d " + remoteTargetDir;
493 cmd += "-d " + remoteTargetDir;
504494 }
505495
506496 try {
512502 if (channel != null) {
513503 channel.disconnect();
514504 }
515 throw (IOException) new IOException("Error during SCP transfer." + e.getMessage())
516 .initCause(e);
505 throw new IOException("Error during SCP transfer." + e.getMessage(), e);
517506 }
518507 }
519508
520509 /**
521510 * Download a file from the remote server to a local file.
522 *
511 *
523512 * @param remoteFile
524513 * Path and name of the remote file.
525514 * @param localTarget
537526
538527 /**
539528 * Download a file from the remote server into an OutputStream
540 *
529 *
541530 * @param remoteFile
542531 * Path and name of the remote file.
543532 * @param localTarget
547536 * @throws RemoteScpException
548537 * in case of problems on the target system (connection ok)
549538 */
539 @SuppressWarnings("unused")
550540 public void get(String remoteFile, OutputStream localTarget) throws IOException,
551541 RemoteScpException {
552542 ChannelExec channel = null;
553543
554 if ((remoteFile == null) || (localTarget == null)) {
544 if (remoteFile == null || localTarget == null) {
555545 throw new IllegalArgumentException("Null argument.");
556546 }
557547
566556 if (channel != null) {
567557 channel.disconnect();
568558 }
569 throw (IOException) new IOException("Error during SCP transfer." + e.getMessage())
570 .initCause(e);
559 throw new IOException("Error during SCP transfer. " + e.getMessage(), e);
571560 }
572561 }
573562
574563 /**
575564 * Initiates an SCP sequence but stops after getting fileinformation header
576 *
565 *
577566 * @param remoteFile
578567 * to get information for
579568 * @return the file information got
598587 fileInfo = receiveStream(channel, remoteFile, null);
599588 channel.disconnect();
600589 } catch (JSchException e) {
601 throw (IOException) new IOException("Error during SCP transfer." + e.getMessage())
602 .initCause(e);
590 throw new IOException("Error during SCP transfer. " + e.getMessage(), e);
603591 } finally {
604592 if (channel != null) {
605593 channel.disconnect();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5252 private static final int SSH_DEFAULT_PORT = 22;
5353
5454 private SshCache() {
55 };
55 }
5656
5757 private static SshCache instance = new SshCache();
5858
107107
108108 /**
109109 * attach an sftp channel to this cache entry
110 *
110 *
111111 * @param newChannel
112112 * to attach
113113 */
149149
150150 /**
151151 * key is username / host / port
152 *
153 * @see SshCache.createCacheKey() for details
154 */
155 private Map uriCacheMap = new HashMap();
152 *
153 * @see #createCacheKey(String, String, int) for details
154 */
155 private final Map<String, Entry> uriCacheMap = new HashMap<>();
156156
157157 /**
158158 * key is the session itself
159159 */
160 private Map sessionCacheMap = new HashMap();
160 private final Map<Session, Entry> sessionCacheMap = new HashMap<>();
161161
162162 /**
163163 * retrieves a session entry for a given hostname from the cache
164 *
165 * @param hostname
164 *
165 * @param user
166166 * to retrieve session for
167 * @param host
168 * ditto
169 * @param port
170 * ditto
167171 * @return null or the existing entry
168172 */
169173 private Entry getCacheEntry(String user, String host, int port) {
170 return (Entry) uriCacheMap.get(createCacheKey(user, host, port));
171 }
172
173 /**
174 * Creates a cobined cache key from the given key parts
175 *
174 return uriCacheMap.get(createCacheKey(user, host, port));
175 }
176
177 /**
178 * Creates a combined cache key from the given key parts
179 *
176180 * @param user
177181 * name of the user
178182 * @param host
186190 if (port != -1 && port != SSH_DEFAULT_PORT) {
187191 portToUse = Integer.toString(port);
188192 }
189 return user.toLowerCase(Locale.US).trim() + "@" + host.toLowerCase(Locale.US).trim() + ":"
193 return user.trim().toLowerCase(Locale.US) + "@" + host.trim().toLowerCase(Locale.US) + ":"
190194 + portToUse;
191195 }
192196
193197 /**
194198 * retrieves a session entry for a given session from the cache
195 *
199 *
196200 * @param session
197201 * to retrieve cache entry for
198202 * @return null or the existing entry
199203 */
200204 private Entry getCacheEntry(Session session) {
201 return (Entry) sessionCacheMap.get(session);
205 return sessionCacheMap.get(session);
202206 }
203207
204208 /**
205209 * Sets a session to a given combined key into the cache If an old session object already
206210 * exists, close and remove it
207 *
211 *
208212 * @param user
209213 * of the session
210214 * @param host
215219 * Session to save
216220 */
217221 private void setSession(String user, String host, int port, Session newSession) {
218 Entry entry = (Entry) uriCacheMap.get(createCacheKey(user, host, port));
222 Entry entry = uriCacheMap.get(createCacheKey(user, host, port));
219223 Session oldSession = null;
220224 if (entry != null) {
221225 oldSession = entry.getSession();
227231 oldSession.disconnect();
228232 Message.verbose(":: SSH :: ssh connection closed from " + oldhost);
229233 }
230 if ((newSession == null) && (entry != null)) {
234 if (newSession == null && entry != null) {
231235 uriCacheMap.remove(createCacheKey(user, host, port));
232236 if (entry.getSession() != null) {
233237 sessionCacheMap.remove(entry.getSession());
240244 }
241245
242246 /**
243 * discardes session entries from the cache
244 *
247 * discards session entries from the cache
248 *
245249 * @param session
246250 * to clear
247251 */
248252 public void clearSession(Session session) {
249 Entry entry = (Entry) sessionCacheMap.get(session);
253 Entry entry = sessionCacheMap.get(session);
250254 if (entry != null) {
251255 setSession(entry.getUser(), entry.getHost(), entry.getPort(), null);
252256 }
254258
255259 /**
256260 * retrieves an sftp channel from the cache
257 *
261 *
258262 * @param session
259263 * to connect to
260264 * @return channelSftp or null if not successful (channel not existent or dead)
265 * @throws IOException should never happen
261266 */
262267 public ChannelSftp getChannelSftp(Session session) throws IOException {
263268 ChannelSftp channel = null;
274279
275280 /**
276281 * attaches a channelSftp to an existing session cache entry
277 *
282 *
278283 * @param session
279284 * to attach the channel to
280285 * @param channel
290295
291296 /**
292297 * Attempts to connect to a local SSH agent (using either UNIX sockets or PuTTY's Pageant)
293 *
298 *
294299 * @param jsch
295300 * Connection to be attached to an available local agent
296301 * @return true if connected to agent, false otherwise
308313
309314 /**
310315 * Gets a session from the cache or establishes a new session if necessary
311 *
316 *
312317 * @param host
313318 * to connect to
314319 * @param port
326331 * @param allowedAgentUse
327332 * Whether to communicate with an agent for authentication
328333 * @return session or null if not successful
334 * @throws IOException if something goes wrong
329335 */
330336 public Session getSession(String host, int port, String username, String userPassword,
331337 File pemFile, String pemPassword, File passFile, boolean allowedAgentUse)
368374 if (passFile != null && passFile.exists()) {
369375 passFile.delete();
370376 }
371 IOException ex = new IOException(e.getMessage());
372 ex.initCause(e);
373 throw ex;
377 throw new IOException(e.getMessage(), e);
374378 }
375379 }
376380 return session;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 import java.util.ArrayList;
2929 import java.util.List;
3030
31 import org.apache.ivy.core.settings.TimeoutConstraint;
3132 import org.apache.ivy.plugins.repository.Resource;
3233 import org.apache.ivy.util.Message;
3334
5657
5758 private String publishPermissions = null;
5859
60 public SshRepository() {
61
62 }
63
64 public SshRepository(final TimeoutConstraint timeoutConstraint) {
65 super(timeoutConstraint);
66 }
67
5968 /**
6069 * create a new resource with lazy initializing
70 *
71 * @param source String
72 * @return Resource
6173 */
6274 public Resource getResource(String source) {
6375 Message.debug("SShRepository:getResource called: " + source);
6779 /**
6880 * Fetch the needed file information for a given file (size, last modification time) and report
6981 * it back in a SshResource
70 *
82 *
7183 * @param source
7284 * ssh uri for the file to get info for
73 * @return SshResource filled with the needed informations
85 * @return SshResource filled with the needed information
7486 * @see org.apache.ivy.plugins.repository.Repository#getResource(java.lang.String)
7587 */
7688 public SshResource resolveResource(String source) {
8395 Scp.FileInfo fileInfo = myCopy.getFileinfo(new URI(source).getPath());
8496 result = new SshResource(this, source, true, fileInfo.getLength(),
8597 fileInfo.getLastModified());
86 } catch (IOException e) {
87 if (session != null) {
88 releaseSession(session, source);
89 }
90 result = new SshResource();
91 } catch (URISyntaxException e) {
98 } catch (IOException | URISyntaxException e) {
9299 if (session != null) {
93100 releaseSession(session, source);
94101 }
102109
103110 /**
104111 * Reads out the output of a ssh session exec
105 *
112 *
106113 * @param channel
107114 * Channel to read from
108115 * @param strStdout
109 * StringBuffer that receives Session Stdout output
116 * StringBuilder that receives Session Stdout output
110117 * @param strStderr
111 * StringBuffer that receives Session Stderr output
118 * StringBuilder that receives Session Stderr output
112119 * @throws IOException
113120 * in case of trouble with the network
114121 */
115 private void readSessionOutput(ChannelExec channel, StringBuffer strStdout,
116 StringBuffer strStderr) throws IOException {
122 private void readSessionOutput(ChannelExec channel, StringBuilder strStdout,
123 StringBuilder strStderr) throws IOException {
117124 InputStream stdout = channel.getInputStream();
118125 InputStream stderr = channel.getErrStream();
119126
120127 try {
121128 channel.connect();
122 } catch (JSchException e1) {
123 throw (IOException) new IOException("Channel connection problems").initCause(e1);
129 } catch (JSchException jsche) {
130 throw new IOException("Channel connection problems", jsche);
124131 }
125132
126133 byte[] buffer = new byte[BUFFER_SIZE];
156163
157164 /*
158165 * (non-Javadoc)
159 *
166 *
160167 * @see org.apache.ivy.repository.Repository#list(java.lang.String)
161168 */
162 public List list(String parent) throws IOException {
169 public List<String> list(String parent) throws IOException {
163170 Message.debug("SShRepository:list called: " + parent);
164 ArrayList result = new ArrayList();
171 List<String> result = new ArrayList<>();
165172 Session session = null;
166173 ChannelExec channel = null;
167174 session = getSession(parent);
170177 try {
171178 parentUri = new URI(parent);
172179 } catch (URISyntaxException e) {
173 IOException ioe = new IOException("The uri '" + parent + "' is not valid!");
174 ioe.initCause(e);
175 throw ioe;
180 throw new IOException("The uri '" + parent + "' is not valid!", e);
176181 }
177182 String fullCmd = replaceArgument(listCommand, parentUri.getPath());
178183 channel.setCommand(fullCmd);
179 StringBuffer stdOut = new StringBuffer();
180 StringBuffer stdErr = new StringBuffer();
184 StringBuilder stdOut = new StringBuilder();
185 StringBuilder stdErr = new StringBuilder();
181186 readSessionOutput(channel, stdOut, stdErr);
182187 if (channel.getExitStatus() != 0) {
183188 Message.error("Ssh ListCommand exited with status != 0");
194199 }
195200
196201 /**
197 * @param session
198 * @return
199 * @throws JSchException
202 * @param session Session
203 * @return ChannelExec
200204 */
201205 private ChannelExec getExecChannel(Session session) throws IOException {
202206 ChannelExec channel;
211215 /**
212216 * Replace the argument placeholder with argument or append the argument if no placeholder is
213217 * present
214 *
218 *
215219 * @param command
216220 * with argument placeholder or not
217 * @param argument
221 * @param argument ditto
218222 * @return replaced full command
219223 */
220224 private String replaceArgument(String command, String argument) {
221225 String fullCmd;
222 if (command.indexOf(ARGUMENT_PLACEHOLDER) == -1) {
226 if (!command.contains(ARGUMENT_PLACEHOLDER)) {
223227 fullCmd = command + " " + argument;
224228 } else {
225229 fullCmd = command.replaceAll(ARGUMENT_PLACEHOLDER, argument);
229233
230234 /*
231235 * (non-Javadoc)
232 *
236 *
233237 * @see org.apache.ivy.repository.Repository#put(java.io.File, java.lang.String, boolean)
234238 */
235239 public void put(File source, String destination, boolean overwrite) throws IOException {
240244 try {
241245 destinationUri = new URI(destination);
242246 } catch (URISyntaxException e) {
243 IOException ioe = new IOException("The uri '" + destination + "' is not valid!");
244 ioe.initCause(e);
245 throw ioe;
247 throw new IOException("The uri '" + destination + "' is not valid!", e);
246248 }
247249
248250 try {
279281
280282 /**
281283 * Tries to create a directory path on the target system
282 *
284 *
283285 * @param path
284286 * to create
285 * @param connnection
287 * @param session
286288 * to use
287289 */
288290 private void makePath(String path, Session session) throws IOException {
304306 String mkdir = replaceArgument(createDirCommand, trimmed);
305307 Message.debug("SShRepository: trying to create path: " + mkdir);
306308 channel.setCommand(mkdir);
307 StringBuffer stdOut = new StringBuffer();
308 StringBuffer stdErr = new StringBuffer();
309 StringBuilder stdOut = new StringBuilder();
310 StringBuilder stdErr = new StringBuilder();
309311 readSessionOutput(channel, stdOut, stdErr);
310312 } finally {
311313 if (channel != null) {
316318
317319 /**
318320 * check for existence of file or dir on target system
319 *
321 *
320322 * @param filePath
321323 * to the object to check
322324 * @param session
329331 channel = getExecChannel(session);
330332 String fullCmd = replaceArgument(existCommand, filePath);
331333 channel.setCommand(fullCmd);
332 StringBuffer stdOut = new StringBuffer();
333 StringBuffer stdErr = new StringBuffer();
334 StringBuilder stdOut = new StringBuilder();
335 StringBuilder stdErr = new StringBuilder();
334336 readSessionOutput(channel, stdOut, stdErr);
335337 return channel.getExitStatus() == 0;
336338 }
337339
338340 /*
339341 * (non-Javadoc)
340 *
342 *
341343 * @see org.apache.ivy.repository.Repository#get(java.lang.String, java.io.File)
342344 */
343345 public void get(String source, File destination) throws IOException {
352354 try {
353355 sourceUri = new URI(source);
354356 } catch (URISyntaxException e) {
355 IOException ioe = new IOException("The uri '" + source + "' is not valid!");
356 ioe.initCause(e);
357 throw ioe;
357 throw new IOException("The uri '" + source + "' is not valid!", e);
358358 }
359359
360360 try {
373373 /**
374374 * sets the list command to use for a directory listing listing must be only the filename and
375375 * each filename on a separate line
376 *
376 *
377377 * @param cmd
378378 * to use. default is "ls -1"
379379 */
422422 * The file separator is the separator to use on the target system On a unix system it is '/',
423423 * but I don't know, how this is solved on different ssh implementations. Using the default
424424 * might be fine
425 *
425 *
426426 * @param fileSeparator
427427 * The fileSeparator to use. default '/'
428428 */
433433 /**
434434 * A four digit string (e.g., 0644, see "man chmod", "man open") specifying the permissions of
435435 * the published files.
436 *
437 * @param permissions String
436438 */
437439 public void setPublishPermissions(String permissions) {
438440 this.publishPermissions = permissions;
441443 /**
442444 * return ssh as scheme use the Resolver type name here? would be nice if it would be static, so
443445 * we could use SshResolver.getTypeName()
446 *
447 * @return String
444448 */
445449 protected String getRepositoryScheme() {
446450 return "ssh";
448452
449453 /**
450454 * Not really streaming...need to implement a proper streaming approach?
451 *
455 *
452456 * @param resource
453457 * to stream
454458 * @return InputStream of the resource data
459 * @throws IOException if something goes wrong
455460 */
456461 public InputStream openStream(SshResource resource) throws IOException {
457462 Session session = getSession(resource.getName());
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6161
6262 /*
6363 * (non-Javadoc)
64 *
64 *
6565 * @see org.apache.ivy.repository.Resource#exists()
6666 */
6767 public boolean exists() {
7373
7474 /*
7575 * (non-Javadoc)
76 *
76 *
7777 * @see org.apache.ivy.repository.Resource#getContentLength()
7878 */
7979 public long getContentLength() {
8585
8686 /*
8787 * (non-Javadoc)
88 *
88 *
8989 * @see org.apache.ivy.repository.Resource#getLastModified()
9090 */
9191 public long getLastModified() {
107107
108108 /*
109109 * (non-Javadoc)
110 *
110 *
111111 * @see org.apache.ivy.repository.Resource#getName()
112112 */
113113 public String getName() {
115115 }
116116
117117 public String toString() {
118 StringBuffer buffer = new StringBuffer();
119 buffer.append("SshResource:");
120 buffer.append(uri);
121 buffer.append(" (");
122 buffer.append(len);
123 buffer.append(")]");
124 return buffer.toString();
118 return "SshResource:" + uri + " (" + len + ")]";
125119 }
126120
127121 public boolean isLocal() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.io.File;
2020 import java.io.IOException;
21 import java.util.Iterator;
2221 import java.util.List;
2322
2423 import org.apache.ivy.plugins.repository.AbstractRepository;
2928
3029 public class ChainedRepository extends AbstractRepository {
3130
32 private List/* Repository */repositories;
31 private List<Repository> repositories;
3332
34 public void setRepositories(List/* Repository */repositories) {
33 public void setRepositories(List<Repository> repositories) {
3534 this.repositories = repositories;
3635 }
3736
3837 public Resource getResource(String source) throws IOException {
39 Iterator it = repositories.iterator();
40 while (it.hasNext()) {
41 Repository repository = (Repository) it.next();
38 for (Repository repository : repositories) {
4239 logTry(repository);
4340 try {
4441 Resource r = repository.getResource(source);
5552 }
5653
5754 public void get(String source, File destination) throws IOException {
58 Iterator it = repositories.iterator();
59 while (it.hasNext()) {
60 Repository repository = (Repository) it.next();
55 for (Repository repository : repositories) {
6156 logTry(repository);
6257 boolean ok = false;
6358 try {
7469 throw newIOEFail("copy " + source + " into " + destination);
7570 }
7671
77 public List list(String parent) throws IOException {
78 Iterator it = repositories.iterator();
79 while (it.hasNext()) {
80 Repository repository = (Repository) it.next();
72 public List<String> list(String parent) throws IOException {
73 for (Repository repository : repositories) {
8174 logTry(repository);
8275 try {
83 List list = repository.list(parent);
76 List<String> list = repository.list(parent);
8477 if (list != null) {
8578 logSuccess(repository);
8679 return list;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 import java.util.Collections;
2626 import java.util.HashMap;
2727 import java.util.List;
28 import java.util.ListIterator;
2928 import java.util.Map;
3029
30 import org.apache.ivy.core.settings.TimeoutConstraint;
3131 import org.apache.ivy.plugins.repository.AbstractRepository;
3232 import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
3333 import org.apache.ivy.plugins.repository.Resource;
3838 public class URLRepository extends AbstractRepository {
3939 private RepositoryCopyProgressListener progress = new RepositoryCopyProgressListener(this);
4040
41 private Map resourcesCache = new HashMap();
41 private final Map<String, Resource> resourcesCache = new HashMap<>();
42
43 public URLRepository() {
44 }
45
46 public URLRepository(final TimeoutConstraint timeoutConstraint) {
47 super(timeoutConstraint);
48 }
4249
4350 public Resource getResource(String source) throws IOException {
44 Resource res = (Resource) resourcesCache.get(source);
51 Resource res = resourcesCache.get(source);
4552 if (res == null) {
46 res = new URLResource(new URL(source));
53 res = new URLResource(new URL(source), this.getTimeoutConstraint());
4754 resourcesCache.put(source, res);
4855 }
4956 return res;
5562 Resource res = getResource(source);
5663 long totalLength = res.getContentLength();
5764 if (totalLength > 0) {
58 progress.setTotalLength(new Long(totalLength));
65 progress.setTotalLength(totalLength);
5966 }
60 FileUtil.copy(new URL(source), destination, progress);
61 } catch (IOException ex) {
62 fireTransferError(ex);
63 throw ex;
64 } catch (RuntimeException ex) {
67 FileUtil.copy(new URL(source), destination, progress, getTimeoutConstraint());
68 } catch (IOException | RuntimeException ex) {
6569 fireTransferError(ex);
6670 throw ex;
6771 } finally {
7882 try {
7983 long totalLength = source.length();
8084 if (totalLength > 0) {
81 progress.setTotalLength(new Long(totalLength));
85 progress.setTotalLength(totalLength);
8286 }
83 FileUtil.copy(source, new URL(destination), progress);
84 } catch (IOException ex) {
85 fireTransferError(ex);
86 throw ex;
87 } catch (RuntimeException ex) {
87 FileUtil.copy(source, new URL(destination), progress, getTimeoutConstraint());
88 } catch (IOException | RuntimeException ex) {
8889 fireTransferError(ex);
8990 throw ex;
9091 } finally {
9495
9596 private ApacheURLLister lister = new ApacheURLLister();
9697
97 public List list(String parent) throws IOException {
98 public List<String> list(String parent) throws IOException {
9899 if (parent.startsWith("http")) {
99 List urls = lister.listAll(new URL(parent));
100 List<URL> urls = lister.listAll(new URL(parent));
100101 if (urls != null) {
101 List ret = new ArrayList(urls.size());
102 for (ListIterator iter = urls.listIterator(); iter.hasNext();) {
103 URL url = (URL) iter.next();
102 List<String> ret = new ArrayList<>(urls.size());
103 for (URL url : urls) {
104104 ret.add(url.toExternalForm());
105105 }
106106 return ret;
115115 path = uri.getPath();
116116 }
117117 } catch (URISyntaxException e) {
118 IOException ioe = new IOException("Couldn't list content of '" + parent + "'");
119 ioe.initCause(e);
120 throw ioe;
118 throw new IOException("Couldn't list content of '" + parent + "'", e);
121119 }
122120
123121 File file = new File(path);
124122 if (file.exists() && file.isDirectory()) {
125123 String[] files = file.list();
126 List ret = new ArrayList(files.length);
124 List<String> ret = new ArrayList<>(files.length);
127125 URL context = path.endsWith("/") ? new URL(parent) : new URL(parent + "/");
128 for (int i = 0; i < files.length; i++) {
129 ret.add(new URL(context, files[i]).toExternalForm());
126 for (String fileName : files) {
127 ret.add(new URL(context, fileName).toExternalForm());
130128 }
131129 return ret;
132130 } else {
133 return Collections.EMPTY_LIST;
131 return Collections.emptyList();
134132 }
135133
136134 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.net.URISyntaxException;
2424 import java.net.URL;
2525
26 import org.apache.ivy.core.settings.TimeoutConstraint;
2627 import org.apache.ivy.plugins.repository.LocalizableResource;
2728 import org.apache.ivy.plugins.repository.Resource;
29 import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
30 import org.apache.ivy.util.url.URLHandler;
2831 import org.apache.ivy.util.url.URLHandler.URLInfo;
2932 import org.apache.ivy.util.url.URLHandlerRegistry;
3033
3134 public class URLResource implements LocalizableResource {
32 private URL url;
35 private final URL url;
36
37 private final TimeoutConstraint timeoutConstraint;
3338
3439 private boolean init = false;
3540
3944
4045 private boolean exists;
4146
42 public URLResource(URL url) {
47 public URLResource(final URL url) {
48 this(url, null);
49 }
50
51 public URLResource(final URL url, final TimeoutConstraint timeoutConstraint) {
4352 this.url = url;
53 this.timeoutConstraint = timeoutConstraint;
4454 }
4555
4656 public String getName() {
6373 return lastModified;
6474 }
6575
76 @SuppressWarnings("deprecation")
6677 private void init() {
67 URLInfo info = URLHandlerRegistry.getDefault().getURLInfo(url);
78 final URLHandler handler = URLHandlerRegistry.getDefault();
79 final URLInfo info;
80 if (handler instanceof TimeoutConstrainedURLHandler) {
81 info = ((TimeoutConstrainedURLHandler) handler).getURLInfo(this.url, this.timeoutConstraint);
82 } else {
83 info = handler.getURLInfo(this.url);
84 }
6885 contentLength = info.getContentLength();
6986 lastModified = info.getLastModified();
7087 exists = info.isReachable();
97114 return url.getProtocol().equals("file");
98115 }
99116
117 @SuppressWarnings("deprecation")
100118 public InputStream openStream() throws IOException {
101 return URLHandlerRegistry.getDefault().openStream(url);
119 final URLHandler handler = URLHandlerRegistry.getDefault();
120 if (handler instanceof TimeoutConstrainedURLHandler) {
121 return ((TimeoutConstrainedURLHandler) handler).openStream(this.url, this.timeoutConstraint);
122 }
123 return handler.openStream(this.url);
102124 }
103125
104126 public File getFile() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.util.Arrays;
2525 import java.util.List;
2626
27 import org.apache.commons.vfs.FileContent;
28 import org.apache.commons.vfs.FileObject;
29 import org.apache.commons.vfs.FileSystemException;
30 import org.apache.commons.vfs.FileSystemManager;
31 import org.apache.commons.vfs.FileType;
32 import org.apache.commons.vfs.impl.StandardFileSystemManager;
27 import org.apache.commons.vfs2.FileContent;
28 import org.apache.commons.vfs2.FileObject;
29 import org.apache.commons.vfs2.FileSystemException;
30 import org.apache.commons.vfs2.FileSystemManager;
31 import org.apache.commons.vfs2.FileType;
32 import org.apache.commons.vfs2.impl.StandardFileSystemManager;
33 import org.apache.ivy.core.settings.TimeoutConstraint;
3334 import org.apache.ivy.plugins.repository.AbstractRepository;
3435 import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
3536 import org.apache.ivy.plugins.repository.Resource;
5556 * Create a new Ivy VFS Repository Instance
5657 */
5758 public VfsRepository() {
59 }
60
61 public VfsRepository(final TimeoutConstraint timeoutConstraint) {
62 super(timeoutConstraint);
5863 }
5964
6065 private FileSystemManager getVFSManager() throws IOException {
8792 Message.verbose("Available VFS schemes...");
8893 String[] schemes = result.getSchemes();
8994 Arrays.sort(schemes);
90 for (int i = 0; i < schemes.length; i++) {
91 Message.verbose("VFS Supported Scheme: " + schemes[i]);
95 for (String scheme : schemes) {
96 Message.verbose("VFS Supported Scheme: " + scheme);
9297 }
9398 } catch (FileSystemException e) {
9499 /*
99104 */
100105 Message.error("Unable to initialize VFS repository manager!");
101106 Message.error(e.getLocalizedMessage());
102 IOException error = new IOException(e.getLocalizedMessage());
103 error.initCause(e);
104 throw error;
107 throw new IOException(e.getLocalizedMessage(), e);
105108 }
106109
107110 return result;
116119
117120 /**
118121 * Get a VfsResource
119 *
120 * @param source
122 *
123 * @param vfsURI
121124 * a <code>String</code> identifying a VFS Resource
122 * @throws <code>IOException</code> on failure
125 * @return Resource
126 * @throws IOException on failure
123127 * @see "Supported File Systems in the jakarta-commons-vfs documentation"
124128 */
125129 public Resource getResource(String vfsURI) throws IOException {
128132
129133 /**
130134 * Transfer a VFS Resource from the repository to the local file system.
131 *
135 *
132136 * @param srcVfsURI
133137 * a <code>String</code> identifying the VFS resource to be fetched
134138 * @param destination
135139 * a <code>File</code> identifying the destination file
136 * @throws <code>IOException</code> on failure
140 * @throws IOException on failure
137141 * @see "Supported File Systems in the jakarta-commons-vfs documentation"
138142 */
139143 public void get(String srcVfsURI, File destination) throws IOException {
146150 + ": no content found");
147151 }
148152 FileUtil.copy(content.getInputStream(), destination, progress);
149 } catch (IOException ex) {
153 } catch (IOException | RuntimeException ex) {
150154 fireTransferError(ex);
151155 throw ex;
152 } catch (RuntimeException ex) {
153 fireTransferError(ex);
154 throw ex;
155156 }
156157 }
157158
158159 /**
159160 * Return a listing of the contents of a parent directory. Listing is a set of strings
160161 * representing VFS URIs.
161 *
162 *
162163 * @param vfsURI
163164 * providing identifying a VFS provided resource
165 * @return List
164166 * @throws IOException
165167 * on failure.
166168 * @see "Supported File Systems in the jakarta-commons-vfs documentation"
167169 */
168 public List list(String vfsURI) throws IOException {
169 ArrayList list = new ArrayList();
170 public List<String> list(String vfsURI) throws IOException {
171 List<String> list = new ArrayList<>();
170172 Message.debug("list called for URI" + vfsURI);
171173 FileObject resourceImpl = getVFSManager().resolveFile(vfsURI);
172174 Message.debug("resourceImpl=" + resourceImpl.toString());
173175 Message.debug("resourceImpl.exists()" + resourceImpl.exists());
174176 Message.debug("resourceImpl.getType()" + resourceImpl.getType());
175177 Message.debug("FileType.FOLDER" + FileType.FOLDER);
176 if ((resourceImpl != null) && resourceImpl.exists()
177 && (resourceImpl.getType() == FileType.FOLDER)) {
178 FileObject[] children = resourceImpl.getChildren();
179 for (int i = 0; i < children.length; i++) {
180 FileObject child = children[i];
181 Message.debug("child " + i + child.getName().getURI());
178 if (resourceImpl.exists() && resourceImpl.getType() == FileType.FOLDER) {
179 List<FileObject> children = Arrays.asList(resourceImpl.getChildren());
180 for (FileObject child : children) {
181 Message.debug("child " + children.indexOf(child) + child.getName().getURI());
182182 list.add(VfsResource.normalize(child.getName().getURI()));
183183 }
184184 }
187187
188188 /**
189189 * Transfer an Ivy resource to a VFS repository
190 *
190 *
191191 * @param source
192 * a <code>File</code> indentifying the local file to transfer to the repository
192 * a <code>File</code> identifying the local file to transfer to the repository
193193 * @param vfsURI
194194 * a <code>String</code> identifying the destination VFS Resource.
195195 * @param overwrite
196196 * whether to overwrite an existing resource.
197 * @throws <code>IOException</code> on failure.
197 * @throws IOException on failure.
198198 * @see "Supported File Systems in the jakarta-commons-vfs documentation"
199199 */
200200 public void put(File source, String vfsURI, boolean overwrite) throws IOException {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.ArrayList;
2222 import java.util.List;
2323
24 import org.apache.commons.vfs.FileContent;
25 import org.apache.commons.vfs.FileObject;
26 import org.apache.commons.vfs.FileSystemException;
27 import org.apache.commons.vfs.FileSystemManager;
28 import org.apache.commons.vfs.FileType;
24 import org.apache.commons.vfs2.FileContent;
25 import org.apache.commons.vfs2.FileObject;
26 import org.apache.commons.vfs2.FileSystemException;
27 import org.apache.commons.vfs2.FileSystemManager;
28 import org.apache.commons.vfs2.FileType;
2929 import org.apache.ivy.plugins.repository.Resource;
3030 import org.apache.ivy.plugins.resolver.VfsResolver;
3131 import org.apache.ivy.util.Message;
6262 try {
6363 resourceImpl = fsManager.resolveFile(vfsURI);
6464 content = resourceImpl.getContent();
65
6665 exists = resourceImpl.exists();
6766 lastModified = content.getLastModifiedTime();
6867 contentLength = content.getSize();
7372 lastModified = 0;
7473 contentLength = 0;
7574 }
76
7775 init = true;
7876 }
7977 }
8078
8179 /**
82 * Get a list of direct descendents of the given resource. Note that attempts to get a list of
83 * children does <emphasize>not</emphasize> result in an error. Instead an error message is
80 * Get a list of direct descendants of the given resource. Note that attempts to get a list of
81 * children does <em>not</em> result in an error. Instead an error message is
8482 * logged and an empty ArrayList returned.
85 *
83 *
8684 * @return A <code>ArrayList</code> of VFSResources
8785 */
88 public List getChildren() {
89 init();
90 ArrayList list = new ArrayList();
86 public List<String> getChildren() {
87 init();
88 List<String> list = new ArrayList<>();
9189 try {
92 if ((resourceImpl != null) && resourceImpl.exists()
93 && (resourceImpl.getType() == FileType.FOLDER)) {
94 FileObject[] children = resourceImpl.getChildren();
95 for (int i = 0; i < children.length; i++) {
96 FileObject child = children[i];
90 if (resourceImpl != null && resourceImpl.exists()
91 && resourceImpl.getType() == FileType.FOLDER) {
92 for (FileObject child : resourceImpl.getChildren()) {
9793 list.add(normalize(child.getName().getURI()));
9894 }
9995 }
111107
112108 /**
113109 * Get the name of the resource.
114 *
110 *
115111 * @return a <code>String</code> representing the Resource URL.
116112 */
117113 public String getName() {
125121 /**
126122 * The VFS FileName getURI method seems to have a bug in it where file: URIs will have 4 forward
127123 * slashes instead of 3.
128 *
129 * @param vfsURI
130 * @return a normalized <class>String</class> representing the VFS URI
124 *
125 * @param vfsURI ditto
126 * @return a normalized String representing the VFS URI
131127 */
132128 public static String normalize(String vfsURI) {
133129 if (vfsURI == null) {
142138
143139 /**
144140 * Get the last modification time of the resource.
145 *
141 *
146142 * @return a <code>long</code> indicating last modified time.
147143 */
148144 public long getLastModified() {
152148
153149 /**
154150 * Get the size of the resource
155 *
151 *
156152 * @return a <code>long</code> representing the size of the resource (in bytes).
157153 */
158154 public long getContentLength() {
162158
163159 /**
164160 * Flag indicating whether a resource is available for querying
165 *
161 *
166162 * @return <code>true</code> if the resource is available for querying, <code>false</code>
167163 * otherwise.
168164 */
173169
174170 /**
175171 * Return a flag indicating whether a provided VFS resource physically exists
176 *
172 *
177173 * @return <code>true</code> if the resource physically exists, <code>false</code> otherwise.
178174 */
179175 public boolean physicallyExists() {
184180 return resourceImpl.exists();
185181 // originally I only checked for a FileSystemException. I expanded it to
186182 // include all exceptions when I found it would throw a NPE exception when the query was
187 // run on non-wellformed VFS URI.
183 // run on ill-formed VFS URI.
188184 } catch (Exception e) {
189 Message.verbose("Fail to check the existance of the resource " + getName(), e);
185 Message.verbose("Fail to check the existence of the resource " + getName(), e);
190186 return false;
191187 }
192188 }
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
1313 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1414 KIND, either express or implied. See the License for the
1515 specific language governing permissions and limitations
16 under the License.
16 under the License.
1717 -->
18 <!-- For all intents and purposes this is the providers.xml file included
19 in the jakarta-vfs-common distribution with the res and tmp schemas removed.
20 -->
21 <providers>
22 <default-provider class-name="org.apache.commons.vfs.provider.url.UrlFileProvider">
18 <!--
19 For all intents and purposes this is the providers.xml file included
20 in the jakarta-vfs-common distribution with the res and tmp schemas removed.
21 -->
22 <providers>
23 <default-provider class-name="org.apache.commons.vfs2.provider.url.UrlFileProvider">
2324 </default-provider>
24 <provider class-name="org.apache.commons.vfs.provider.local.DefaultLocalFileProvider">
25 <provider class-name="org.apache.commons.vfs2.provider.local.DefaultLocalFileProvider">
2526 <scheme name="file"/>
2627 </provider>
27 <provider class-name="org.apache.commons.vfs.provider.ftp.FtpFileProvider">
28 <provider class-name="org.apache.commons.vfs2.provider.ftp.FtpFileProvider">
2829 <scheme name="ftp"/>
2930 <if-available class-name="org.apache.commons.net.ftp.FTPFile"/>
3031 </provider>
4041 <if-available class-name="org.apache.commons.httpclient.HttpClient"/>
4142 </provider>
4243 -->
43
44 <provider class-name="org.apache.commons.vfs.provider.sftp.SftpFileProvider">
44 <provider class-name="org.apache.commons.vfs2.provider.sftp.SftpFileProvider">
4545 <scheme name="sftp"/>
4646 <if-available class-name="javax.crypto.Cipher"/>
4747 <if-available class-name="com.jcraft.jsch.JSch"/>
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3333 import org.apache.ivy.core.event.IvyEvent;
3434 import org.apache.ivy.core.event.IvyListener;
3535 import org.apache.ivy.core.event.resolve.EndResolveEvent;
36 import org.apache.ivy.core.settings.TimeoutConstraint;
3637 import org.apache.ivy.plugins.repository.AbstractRepository;
3738 import org.apache.ivy.plugins.repository.BasicResource;
3839 import org.apache.ivy.plugins.repository.Resource;
4243
4344 /**
4445 * Repository using SecureCRT vsftp command line program to access an sftp repository This is
45 * especially useful to leverage the gssapi authentication supported by SecureCRT. In caseswhere
46 * especially useful to leverage the gssapi authentication supported by SecureCRT. In cases where
4647 * usual sftp is enough, prefer the 100% java solution of sftp repository. This requires SecureCRT
4748 * to be in the PATH. Tested with SecureCRT 5.0.5
4849 */
9899
99100 private PrintWriter out;
100101
101 private volatile StringBuffer errors = new StringBuffer();
102 private volatile StringBuilder errors = new StringBuilder();
102103
103104 private long readTimeout = DEFAULT_READ_TIMEOUT;
104105
117118 private volatile long errorsLastUpdateTime;
118119
119120 private Ivy ivy = null;
121
122 public VsftpRepository() {
123 }
124
125 public VsftpRepository(final TimeoutConstraint timeoutConstraint) {
126 super(timeoutConstraint);
127 }
120128
121129 public Resource getResource(String source) throws IOException {
122130 initIvy();
151159 }
152160
153161 int index = source.lastIndexOf('/');
154 String srcName = index == -1 ? source : source.substring(index + 1);
155 final File to = destDir == null ? Checks.checkAbsolute(srcName, "source") : new File(
156 destDir, srcName);
162 String srcName = (index == -1) ? source : source.substring(index + 1);
163 final File to = (destDir == null) ? Checks.checkAbsolute(srcName, "source")
164 : new File(destDir, srcName);
157165
158166 final IOException[] ex = new IOException[1];
159167 Thread get = new IvyThread() {
216224 }
217225 }
218226
219 public List list(String parent) throws IOException {
227 public List<String> list(String parent) throws IOException {
220228 initIvy();
221229 try {
222230 if (!parent.endsWith("/")) {
223 parent = parent + "/";
231 parent += "/";
224232 }
225233 String response = sendCommand("ls -l " + parent, true, true);
226234 if (response.startsWith("ls")) {
227235 return null;
228236 }
229237 String[] lines = response.split("\n");
230 List ret = new ArrayList(lines.length);
231 for (int i = 0; i < lines.length; i++) {
232 while (lines[i].endsWith("\r") || lines[i].endsWith("\n")) {
233 lines[i] = lines[i].substring(0, lines[i].length() - 1);
234 }
235 if (lines[i].trim().length() != 0) {
236 ret.add(parent + lines[i].substring(lines[i].lastIndexOf(' ') + 1));
238 List<String> ret = new ArrayList<>(lines.length);
239 for (String line : lines) {
240 while (line.endsWith("\r") || line.endsWith("\n")) {
241 line = line.substring(0, line.length() - 1);
242 }
243 if (!line.trim().isEmpty()) {
244 ret.add(parent + line.substring(line.lastIndexOf(' ') + 1));
237245 }
238246 }
239247 return ret;
304312 * stream, even if everything is ok. So it's quite difficult if there was an error or not. Hence
305313 * we compare the response with the expected message and deal with it. The problem is that this
306314 * is very specific to the version of vsftp used for the test, That's why expected messages are
307 * obtained using overridable protected methods.
315 * obtained using overriddable protected methods.
316 *
317 * @param command String
318 * @param expectedResponse Pattern
319 * @param timeout long
320 * @throws IOException if something goes wrong
308321 */
309322 protected void sendCommand(String command, Pattern expectedResponse, long timeout)
310323 throws IOException {
365378 return readResponse(sendErrorAsResponse, readTimeout);
366379 }
367380
381 @SuppressWarnings("deprecation")
368382 protected synchronized String readResponse(final boolean sendErrorAsResponse, long timeout)
369383 throws IOException {
370 final StringBuffer response = new StringBuffer();
384 final StringBuilder response = new StringBuilder();
371385 final IOException[] exc = new IOException[1];
372386 final boolean[] done = new boolean[1];
373387 Runnable r = new Runnable() {
376390 try {
377391 int c;
378392 boolean getPrompt = false;
379 // the reading is done in a for loop making five attempts to read the stream
393 // the reading is done in a loop making five attempts to read the stream
380394 // if we do not reach the next prompt
381 for (int attempts = 0; !getPrompt && attempts < MAX_READ_PROMPT_ATTEMPT; attempts++) {
395 int attempt = 0;
396 while (!getPrompt && attempt < MAX_READ_PROMPT_ATTEMPT) {
382397 while ((c = in.read()) != -1) {
383 attempts = 0; // we manage to read something, reset numer of
384 // attempts
398 // we managed to read something, reset number of attempts
399 attempt = 0;
385400 response.append((char) c);
386401 if (response.length() >= PROMPT.length()
387402 && response.substring(response.length() - PROMPT.length(),
398413 break;
399414 }
400415 }
416 attempt++;
401417 }
402418 if (getPrompt) {
403419 // wait enough for error stream to be fully read
450466 } else if (!done[0]) {
451467 if (reader != null && reader.isAlive()) {
452468 reader.interrupt();
453 for (int i = 0; i < MAX_READER_ALIVE_ATTEMPT && reader.isAlive(); i++) {
469 int attempt = 0;
470 while (attempt < MAX_READER_ALIVE_ATTEMPT && reader.isAlive()) {
454471 try {
455472 Thread.sleep(READER_ALIVE_SLEEP_TIME);
456473 } catch (InterruptedException e) {
457474 break;
458475 }
476 attempt++;
459477 }
460478 if (reader.isAlive()) {
461479 reader.stop(); // no way to interrupt it non abruptly
496514 sleep(sleep);
497515 sleep = reuseConnection
498516 - (System.currentTimeMillis() - lastCommand);
499 if (inCommand) {
500 sleep = sleep <= 0 ? reuseConnection : sleep;
517 if (inCommand && sleep <= 0) {
518 sleep = reuseConnection;
501519 }
502520 }
503521 } catch (InterruptedException e) {
636654
637655 /**
638656 * Parses a ls -l line and transforms it in a resource
639 *
640 * @param file
641 * @param responseLine
642 * @return
657 *
658 * @param file ditto
659 * @param responseLine ditto
660 * @return Resource
643661 */
644662 protected Resource lslToResource(String file, String responseLine) {
645663 if (responseLine == null || responseLine.startsWith("ls")) {
709727 this.username = username;
710728 }
711729
712 private static StringBuffer chomp(StringBuffer str) {
730 private static StringBuilder chomp(StringBuilder str) {
713731 if (str == null || str.length() == 0) {
714732 return str;
715733 }
727745 /**
728746 * Sets the reuse connection time. The same connection will be reused if the time here does not
729747 * last between two commands. O indicates that the connection should never be reused
730 *
731 * @param time
748 *
749 * @param time long
732750 */
733751 public void setReuseConnection(long time) {
734752 this.reuseConnection = time;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.util.Date;
2424 import java.util.HashMap;
2525 import java.util.HashSet;
26 import java.util.Iterator;
2726 import java.util.LinkedHashSet;
2827 import java.util.List;
29 import java.util.ListIterator;
3028 import java.util.Map;
31 import java.util.Map.Entry;
3229 import java.util.Set;
3330
3431 import org.apache.ivy.core.IvyPatternHelper;
4845 */
4946 public abstract class AbstractPatternsBasedResolver extends BasicResolver {
5047
51 private List ivyPatterns = new ArrayList(); // List (String pattern)
52
53 private List artifactPatterns = new ArrayList(); // List (String pattern)
48 private List<String> ivyPatterns = new ArrayList<>();
49
50 private List<String> artifactPatterns = new ArrayList<>();
5451
5552 private boolean m2compatible = false;
5653
6764 data.getDate());
6865 }
6966
67 @Override
7068 public ResolvedResource findArtifactRef(Artifact artifact, Date date) {
7169 ModuleRevisionId mrid = artifact.getModuleRevisionId();
7270 if (isM2compatible()) {
7674 getDefaultRMDParser(artifact.getModuleRevisionId().getModuleId()), date);
7775 }
7876
77 @Override
7978 public ResolvedResource findResource(ResolvedResource[] rress, ResourceMDParser rmdparser,
8079 ModuleRevisionId mrid, Date date) {
8180 if (isM2compatible()) {
8685 }
8786
8887 protected ResolvedResource findResourceUsingPatterns(ModuleRevisionId moduleRevision,
89 List patternList, Artifact artifact, ResourceMDParser rmdparser, Date date) {
90 List resolvedResources = new ArrayList();
91 Set foundRevisions = new HashSet();
88 List<String> patternList, Artifact artifact, ResourceMDParser rmdparser, Date date) {
89 List<ResolvedResource> resolvedResources = new ArrayList<>();
90 Set<String> foundRevisions = new HashSet<>();
9291 boolean dynamic = getSettings().getVersionMatcher().isDynamic(moduleRevision);
93 boolean stop = false;
94 for (Iterator iter = patternList.iterator(); iter.hasNext() && !stop;) {
95 String pattern = (String) iter.next();
92 for (String pattern : patternList) {
9693 ResolvedResource rres = findResourceUsingPattern(moduleRevision, pattern, artifact,
9794 rmdparser, date);
98 if ((rres != null) && !foundRevisions.contains(rres.getRevision())) {
95 if (rres != null && !foundRevisions.contains(rres.getRevision())) {
9996 // only add the first found ResolvedResource for each revision
10097 foundRevisions.add(rres.getRevision());
10198 resolvedResources.add(rres);
102 stop = !dynamic; // stop iterating if we are not searching a dynamic revision
99 if (!dynamic) {
100 // stop iterating if we are not searching a dynamic revision
101 break;
102 }
103103 }
104104 }
105105
106106 if (resolvedResources.size() > 1) {
107 ResolvedResource[] rress = (ResolvedResource[]) resolvedResources
107 ResolvedResource[] rress = resolvedResources
108108 .toArray(new ResolvedResource[resolvedResources.size()]);
109109 return findResource(rress, rmdparser, moduleRevision, date);
110110 } else if (resolvedResources.size() == 1) {
111 return (ResolvedResource) resolvedResources.get(0);
111 return resolvedResources.get(0);
112112 } else {
113113 return null;
114114 }
117117 protected abstract ResolvedResource findResourceUsingPattern(ModuleRevisionId mrid,
118118 String pattern, Artifact artifact, ResourceMDParser rmdparser, Date date);
119119
120 protected Collection findNames(Map tokenValues, String token) {
121 Collection names = new HashSet();
122 names.addAll(findIvyNames(tokenValues, token));
120 @Override
121 protected Collection<String> findNames(Map<String, String> tokenValues, String token) {
122 Collection<String> names = new HashSet<>(findIvyNames(tokenValues, token));
123123 if (isAllownomd()) {
124124 names.addAll(findArtifactNames(tokenValues, token));
125125 }
126126 return names;
127127 }
128128
129 protected Collection findIvyNames(Map tokenValues, String token) {
130 Collection names = new HashSet();
131 tokenValues = new HashMap(tokenValues);
129 protected Collection<String> findIvyNames(Map<String, String> tokenValues, String token) {
130 Collection<String> names = new HashSet<>();
131 tokenValues = new HashMap<>(tokenValues);
132132 tokenValues.put(IvyPatternHelper.ARTIFACT_KEY, "ivy");
133133 tokenValues.put(IvyPatternHelper.TYPE_KEY, "ivy");
134134 tokenValues.put(IvyPatternHelper.EXT_KEY, "xml");
140140 return names;
141141 }
142142
143 protected Collection findArtifactNames(Map tokenValues, String token) {
144 Collection names = new HashSet();
145 tokenValues = new HashMap(tokenValues);
143 protected Collection<String> findArtifactNames(Map<String, String> tokenValues, String token) {
144 Collection<String> names = new HashSet<>();
145 tokenValues = new HashMap<>(tokenValues);
146146 tokenValues
147147 .put(IvyPatternHelper.ARTIFACT_KEY, tokenValues.get(IvyPatternHelper.MODULE_KEY));
148148 tokenValues.put(IvyPatternHelper.TYPE_KEY, "jar");
155155 return names;
156156 }
157157
158 public Map[] listTokenValues(String[] tokens, Map criteria) {
159 Set result = new LinkedHashSet();
158 @SuppressWarnings("unchecked")
159 @Override
160 public Map<String, String>[] listTokenValues(String[] tokens, Map<String, Object> criteria) {
161 Set<Map<String, String>> result = new LinkedHashSet<>();
160162
161163 // use ivy patterns
162 List ivyPatterns = getIvyPatterns();
163 Map tokenValues = new HashMap(criteria);
164 tokenValues.put(IvyPatternHelper.TYPE_KEY, "ivy");
165 tokenValues.put(IvyPatternHelper.EXT_KEY, getModuleDescriptorExtension());
166 if (isM2compatible()) {
167 convertM2TokenValuesForResourceSearch(tokenValues);
168 }
169 for (Iterator it = ivyPatterns.iterator(); it.hasNext();) {
170 String ivyPattern = (String) it.next();
171 result.addAll(resolveTokenValues(tokens, ivyPattern, tokenValues, false));
164 Map<String, Object> subcriteria = new HashMap<>(criteria);
165 subcriteria.put(IvyPatternHelper.TYPE_KEY, "ivy");
166 subcriteria.put(IvyPatternHelper.EXT_KEY, getModuleDescriptorExtension());
167 if (isM2compatible()) {
168 convertM2CriteriaForResourceSearch(subcriteria);
169 }
170 for (String ivyPattern : getIvyPatterns()) {
171 result.addAll(resolveTokenValues(tokens, ivyPattern, subcriteria, false));
172172 }
173173
174174 if (isAllownomd()) {
175 List artifactPatterns = getArtifactPatterns();
176 tokenValues = new HashMap(criteria);
177 tokenValues.put(IvyPatternHelper.TYPE_KEY, "jar");
178 tokenValues.put(IvyPatternHelper.EXT_KEY, "jar");
175 subcriteria = new HashMap<>(criteria);
176 subcriteria.put(IvyPatternHelper.TYPE_KEY, "jar");
177 subcriteria.put(IvyPatternHelper.EXT_KEY, "jar");
179178 if (isM2compatible()) {
180 convertM2TokenValuesForResourceSearch(tokenValues);
181 }
182 for (Iterator it = artifactPatterns.iterator(); it.hasNext();) {
183 String artifactPattern = (String) it.next();
184 result.addAll(resolveTokenValues(tokens, artifactPattern, tokenValues, true));
185 }
186 }
187
188 return (Map[]) result.toArray(new Map[result.size()]);
179 convertM2CriteriaForResourceSearch(subcriteria);
180 }
181 for (String artifactPattern : getArtifactPatterns()) {
182 result.addAll(resolveTokenValues(tokens, artifactPattern, subcriteria, true));
183 }
184 }
185
186 return result.toArray(new Map[result.size()]);
189187 }
190188
191189 protected String getModuleDescriptorExtension() {
192190 return "xml";
193191 }
194192
195 private Set resolveTokenValues(String[] tokens, String pattern, Map criteria, boolean noMd) {
196 Set result = new LinkedHashSet();
197 Set tokenSet = new HashSet(Arrays.asList(tokens));
198
199 Map tokenValues = new HashMap();
200 for (Iterator it = criteria.entrySet().iterator(); it.hasNext();) {
201 Map.Entry entry = (Entry) it.next();
202 Object key = entry.getKey();
193 private Set<Map<String, String>> resolveTokenValues(String[] tokens, String pattern,
194 Map<String, Object> criteria, boolean noMd) {
195 Set<Map<String, String>> result = new LinkedHashSet<>();
196 Set<String> tokenSet = new HashSet<>(Arrays.asList(tokens));
197
198 Map<String, String> tokenValues = new HashMap<>();
199 for (Map.Entry<String, Object> entry : criteria.entrySet()) {
203200 Object value = entry.getValue();
204201 if (value instanceof String) {
205 tokenValues.put(key, value);
202 tokenValues.put(entry.getKey(), (String) value);
206203 }
207204 }
208205
214211
215212 String partiallyResolvedPattern = IvyPatternHelper.substituteTokens(pattern, tokenValues);
216213 String token = IvyPatternHelper.getFirstToken(partiallyResolvedPattern);
217 if ((token == null) && exist(partiallyResolvedPattern)) {
214 if (token == null && exist(partiallyResolvedPattern)) {
218215 // no more tokens to resolve
219216 result.add(tokenValues);
220217 return result;
233230 return result;
234231 }
235232
236 List vals = new ArrayList(Arrays.asList(values));
237 filterNames(vals);
238
239 for (Iterator it = vals.iterator(); it.hasNext();) {
240 String value = (String) it.next();
241 if ((matcher != null) && !matcher.matches(value)) {
233 List<String> valueList = new ArrayList<>(Arrays.asList(values));
234 filterNames(valueList);
235
236 for (String value : valueList) {
237 if (matcher != null && !matcher.matches(value)) {
242238 continue;
243239 }
244240
246242 String moreResolvedPattern = IvyPatternHelper.substituteTokens(
247243 partiallyResolvedPattern, tokenValues);
248244
249 Map newCriteria = new HashMap(criteria);
245 Map<String, Object> newCriteria = new HashMap<>(criteria);
250246 newCriteria.put(token, value);
251247 if (noMd && "artifact".equals(token)) {
252248 newCriteria.put("module", value);
253249 } else if (noMd && "module".equals(token)) {
254250 newCriteria.put("artifact", value);
255251 }
256 result.addAll(resolveTokenValues(
257 (String[]) tokenSet.toArray(new String[tokenSet.size()]), moreResolvedPattern,
258 newCriteria, noMd));
252 result.addAll(resolveTokenValues(tokenSet.toArray(new String[tokenSet.size()]),
253 moreResolvedPattern, newCriteria, noMd));
259254 }
260255
261256 return result;
265260
266261 protected abstract boolean exist(String path);
267262
268 protected void findTokenValues(Collection names, List patterns, Map tokenValues, String token) {
263 protected void findTokenValues(Collection<String> names, List<String> patterns,
264 Map<String, String> tokenValues, String token) {
269265 // to be overridden by subclasses wanting to have listing features
270266 }
271267
272268 /**
273269 * example of pattern : ~/Workspace/[module]/[module].ivy.xml
274 *
275 * @param pattern
270 *
271 * @param pattern String
276272 */
277273 public void addIvyPattern(String pattern) {
278274 ivyPatterns.add(pattern);
282278 artifactPatterns.add(pattern);
283279 }
284280
285 public List getIvyPatterns() {
281 public List<String> getIvyPatterns() {
286282 return Collections.unmodifiableList(ivyPatterns);
287283 }
288284
289 public List getArtifactPatterns() {
285 public List<String> getArtifactPatterns() {
290286 return Collections.unmodifiableList(artifactPatterns);
291287 }
292288
293 protected void setIvyPatterns(List patterns) {
289 protected void setIvyPatterns(List<String> patterns) {
294290 ivyPatterns = patterns;
295291 }
296292
297 protected void setArtifactPatterns(List patterns) {
293 protected void setArtifactPatterns(List<String> patterns) {
298294 artifactPatterns = patterns;
299295 }
300296
309305 artifactPatterns.add(p.getPattern());
310306 }
311307
308 @Override
312309 public void dumpSettings() {
313310 super.dumpSettings();
314311 Message.debug("\t\tm2compatible: " + isM2compatible());
315312 Message.debug("\t\tivy patterns:");
316 for (ListIterator iter = getIvyPatterns().listIterator(); iter.hasNext();) {
317 String p = (String) iter.next();
313 for (String p : getIvyPatterns()) {
318314 Message.debug("\t\t\t" + p);
319315 }
320316 Message.debug("\t\tartifact patterns:");
321 for (ListIterator iter = getArtifactPatterns().listIterator(); iter.hasNext();) {
322 String p = (String) iter.next();
317 for (String p : getArtifactPatterns()) {
323318 Message.debug("\t\t\t" + p);
324319 }
325320 }
354349 return org.replace('.', '/');
355350 }
356351
357 protected void convertM2TokenValuesForResourceSearch(Map tokenValues) {
358 if (tokenValues.get(IvyPatternHelper.ORGANISATION_KEY) instanceof String) {
359 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY,
360 convertM2OrganizationForResourceSearch((String) tokenValues
361 .get(IvyPatternHelper.ORGANISATION_KEY)));
352 protected void convertM2TokenValuesForResourceSearch(Map<String, String> tokenValues) {
353 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY,
354 convertM2OrganizationForResourceSearch(tokenValues
355 .get(IvyPatternHelper.ORGANISATION_KEY)));
356 }
357
358 protected void convertM2CriteriaForResourceSearch(Map<String, Object> criteria) {
359 Object org = criteria.get(IvyPatternHelper.ORGANISATION_KEY);
360 if (org instanceof String) {
361 criteria.put(IvyPatternHelper.ORGANISATION_KEY,
362 convertM2OrganizationForResourceSearch((String) org));
362363 }
363364 }
364365
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5353 import org.apache.ivy.core.search.ModuleEntry;
5454 import org.apache.ivy.core.search.OrganisationEntry;
5555 import org.apache.ivy.core.search.RevisionEntry;
56 import org.apache.ivy.core.settings.TimeoutConstraint;
5657 import org.apache.ivy.core.settings.Validatable;
5758 import org.apache.ivy.plugins.conflict.ConflictManager;
5859 import org.apache.ivy.plugins.latest.ArtifactInfo;
110111
111112 private Boolean checkmodified;
112113
114 private String timeoutConstraintName;
115 private TimeoutConstraint timeoutConstraint;
116
113117 public ResolverSettings getSettings() {
114118 return settings;
115119 }
132136
133137 /**
134138 * this method should remove sensitive information from a location to be displayed in a log
135 *
139 *
136140 * @param name
137141 * location
138142 * @return location with sensitive data replaced by stars
143147
144148 protected boolean doValidate(ResolveData data) {
145149 if (validate != null) {
146 return validate.booleanValue();
150 return validate;
147151 } else {
148152 return data.isValidate();
149153 }
150154 }
151155
152156 public boolean isValidate() {
153 return validate == null ? true : validate.booleanValue();
157 return validate == null || validate;
154158 }
155159
156160 public void setValidate(boolean validate) {
157 this.validate = Boolean.valueOf(validate);
161 this.validate = validate;
158162 }
159163
160164 protected void checkInterrupted() {
169173 Message.verbose("no failure report implemented by " + getName());
170174 }
171175
172 public String[] listTokenValues(String token, Map otherTokenValues) {
176 public String[] listTokenValues(String token, Map<String, String> otherTokenValues) {
173177 return new String[0];
174178 }
175179
176 public Map[] listTokenValues(String[] tokens, Map criteria) {
180 @SuppressWarnings("unchecked")
181 public Map<String, String>[] listTokenValues(String[] tokens, Map<String, Object> criteria) {
177182 return new Map[0];
178183 }
179184
189194 return new RevisionEntry[0];
190195 }
191196
197 @Override
192198 public String toString() {
193199 return getName();
194200 }
202208 return getClass().getName();
203209 }
204210
211 public TimeoutConstraint getTimeoutConstraint() {
212 return this.timeoutConstraint;
213 }
214
215 public void setTimeoutConstraint(final String name) {
216 this.timeoutConstraintName = name;
217 }
218
205219 /**
206220 * Default implementation downloads the artifact without taking advantage of its location
221 *
222 * @param artifact ArtifactOrigin
223 * @param options DownloadOptions
224 * @return ArtifactDownloadReport
207225 */
208226 public ArtifactDownloadReport download(ArtifactOrigin artifact, DownloadOptions options) {
209227 DownloadReport r = download(new Artifact[] {artifact.getArtifact()}, options);
217235 /**
218236 * Default implementation actually download the artifact Subclasses should overwrite this to
219237 * avoid the download
238 *
239 * @param artifact ArtifactOrigin
240 * @return ArtifactOrigin
220241 */
221242 public ArtifactOrigin locate(Artifact artifact) {
222243 DownloadReport dr = download(new Artifact[] {artifact}, new DownloadOptions());
223244 if (dr == null) {
224245 /*
225 * according to IVY-831, it seems that this actually happen sometime, while the contract
226 * of DependencyResolver says that it should never return null
246 * according to IVY-831, it seems that this actually happen sometime, while the
247 * contract of DependencyResolver says that it should never return null
227248 */
228249 throw new IllegalStateException("null download report returned by " + getName() + " ("
229250 + getClass().getName() + ")" + " when trying to download " + artifact);
375396 }
376397
377398 public void setCheckmodified(boolean check) {
378 checkmodified = Boolean.valueOf(check);
399 checkmodified = check;
379400 }
380401
381402 public RepositoryCacheManager getRepositoryCacheManager() {
402423 }
403424 }
404425
426 private void initTimeoutConstraintFromSettings() {
427 if (this.timeoutConstraintName == null) {
428 return;
429 }
430 this.timeoutConstraint = settings.getTimeoutConstraint(this.timeoutConstraintName);
431 if (this.timeoutConstraint == null) {
432 throw new IllegalStateException("Unknown timeout constraint '" + this.timeoutConstraintName
433 + "' " + "on resolver '" + this.name + "'");
434 }
435 }
436
405437 public void setRepositoryCacheManager(RepositoryCacheManager repositoryCacheManager) {
406438 this.cacheManagerName = repositoryCacheManager.getName();
407439 this.repositoryCacheManager = repositoryCacheManager;
419451 return eventManager;
420452 }
421453
454 @Override
422455 public void validate() {
423456 initRepositoryCacheManagerFromSettings();
424457 initNamespaceFromSettings();
425458 initLatestStrategyFromSettings();
459 initTimeoutConstraintFromSettings();
426460 }
427461
428462 protected CacheMetadataOptions getCacheOptions(ResolveData data) {
433467 .setCheckmodified(
434468 data.getOptions().isUseCacheOnly() ? Boolean.FALSE : checkmodified)
435469 .setValidate(doValidate(data)).setNamespace(getNamespace())
470 .setUseCacheOnly(data.getOptions().isUseCacheOnly())
436471 .setForce(data.getOptions().isRefresh())
437472 .setListener(getDownloadListener(getDownloadOptions(data.getOptions())));
438473 }
495530 /**
496531 * Returns true if rmr1 is after rmr2, using the latest strategy to determine which is the
497532 * latest
498 *
499 * @param rmr1
500 * @param rmr2
501 * @return
533 *
534 * @param rmr1 ResolvedModuleRevision
535 * @param rmr2 ResolvedModuleRevision
536 * @param date Date
537 * @return boolean
502538 */
503539 protected boolean isAfter(ResolvedModuleRevision rmr1, ResolvedModuleRevision rmr2, Date date) {
504540 ArtifactInfo[] ais = new ArtifactInfo[] {new ResolvedModuleRevisionArtifactInfo(rmr1),
510546 ResolvedModuleRevision newModuleFound, ResolveData data) {
511547 Checks.checkNotNull(dd, "dd");
512548 Checks.checkNotNull(data, "data");
549
550 // always cache dynamic mrids because we can store per-resolver values
551 saveModuleRevisionIfNeeded(dd, newModuleFound);
513552
514553 // check if latest is asked and compare to return the most recent
515554 ResolvedModuleRevision previousModuleFound = data.getCurrentResolvedModuleRevision();
517556 Message.debug("\tchecking " + newModuleDesc + " against " + describe(previousModuleFound));
518557 if (previousModuleFound == null) {
519558 Message.debug("\tmodule revision kept as first found: " + newModuleDesc);
520 saveModuleRevisionIfNeeded(dd, newModuleFound);
521559 return newModuleFound;
522560 } else if (isAfter(newModuleFound, previousModuleFound, data.getDate())) {
523561 Message.debug("\tmodule revision kept as younger: " + newModuleDesc);
524 saveModuleRevisionIfNeeded(dd, newModuleFound);
525562 return newModuleFound;
526563 } else if (!newModuleFound.getDescriptor().isDefault()
527564 && previousModuleFound.getDescriptor().isDefault()) {
528565 Message.debug("\tmodule revision kept as better (not default): " + newModuleDesc);
529 saveModuleRevisionIfNeeded(dd, newModuleFound);
530566 return newModuleFound;
531567 } else {
532568 Message.debug("\tmodule revision discarded as older: " + newModuleDesc);
538574 ResolvedModuleRevision newModuleFound) {
539575 if (newModuleFound != null
540576 && getSettings().getVersionMatcher().isDynamic(dd.getDependencyRevisionId())) {
541 getRepositoryCacheManager().saveResolvedRevision(dd.getDependencyRevisionId(),
542 newModuleFound.getId().getRevision());
577 getRepositoryCacheManager().saveResolvedRevision(getName(),
578 dd.getDependencyRevisionId(), newModuleFound.getId().getRevision());
543579 }
544580 }
545581
593629 return AbstractResolver.this.getSettings().resolveFile(filename);
594630 }
595631
596 public Map substitute(Map strings) {
632 public Map<String, String> substitute(Map<String, String> strings) {
597633 return AbstractResolver.this.getSettings().substitute(strings);
598634 }
599635
601637 return AbstractResolver.this.getSettings().substitute(value);
602638 }
603639
640 public String getVariable(String value) {
641 return AbstractResolver.this.getSettings().getVariable(value);
642 }
643
644 @Override
645 public TimeoutConstraint getTimeoutConstraint(final String name) {
646 return AbstractResolver.this.getSettings().getTimeoutConstraint(name);
647 }
604648 }
605649 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4646
4747 /**
4848 * Sets the location of the Public Key file to use for authentication
49 *
49 *
5050 * @param filePath
5151 * full file path name
5252 */
5656
5757 /**
5858 * Determines whether a local SSH agent may be used for authentication
59 *
59 *
6060 * @param allowedAgentUse
6161 * true if an agent may be used if available
6262 */
6565 }
6666
6767 /**
68 * Optional password file. If set the repository will use it as an encypted property file, to
68 * Optional password file. If set the repository will use it as an encrypted property file, to
6969 * load username and passwd entries, and to store them if the user choose to do so. Defaults to
7070 * user.dir/.ivy/[host].sftp.passwd, set it to null to disable this feature.
71 *
72 * @param passfile File
7173 */
7274 public void setPassfile(File passfile) {
7375 getSshBasedRepository().setPassFile(passfile);
8890 * set and password based login is used, user will be prompted for it the password can also be
8991 * set by using a full url for the pattern, like
9092 * "sftp://user:password@myserver.com/path/to/repos/[artifact].[ext]"
91 *
93 *
9294 * @param password
9395 * to use
9496 */
100102 * Sets the password to use for decrypting key file (if it is encrypted) if no password is set
101103 * and the keyfile is encrypted, the user will be prompted for the password if the keyfile is
102104 * passwordless, this parameter will be ignored if given
103 *
105 *
104106 * @param password
105107 * to use
106108 */
111113 /**
112114 * sets the user to use for the ssh communication the user can also be set by using a full url
113115 * for the pattern, like "ssh://user@myserver.com/path/to/repos/[artifact].[ext]"
114 *
116 *
115117 * @param user
116118 * on the target system
117119 */
122124 /**
123125 * sets the host to use for the ssh communication the host can also be set by using a full url
124126 * for the pattern, like "ssh://myserver.com/path/to/repos/[artifact].[ext]"
125 *
127 *
126128 * @param host
127129 * of the target system
128130 */
134136 * sets the port to use for the ssh communication port 22 is default the port can also be set by
135137 * using a full url for the pattern, like
136138 * "sftp://myserver.com:8022/path/to/repos/[artifact].[ext]"
137 *
139 *
138140 * @param port
139141 * of the target system
140142 */
142144 getSshBasedRepository().setPort(port);
143145 }
144146
147 /**
148 * sets the path to an OpenSSH-style config file to be used for reading configuration values for
149 * an ssh repository, such as a username
150 *
151 * @param sshConfig
152 * path of the config file
153 */
154 public void setSshConfig(String sshConfig) {
155 getSshBasedRepository().setSshConfig(sshConfig);
156 }
157
158 @Override
145159 public abstract String getTypeName();
146160 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.plugins.resolver;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.text.ParseException;
22 import java.util.List;
23
24 import org.apache.ivy.Ivy;
25 import org.apache.ivy.core.module.descriptor.Artifact;
26 import org.apache.ivy.core.module.descriptor.Configuration;
27 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
28 import org.apache.ivy.core.module.descriptor.DefaultWorkspaceModuleDescriptor;
29 import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
30 import org.apache.ivy.core.module.descriptor.ExcludeRule;
31 import org.apache.ivy.core.module.descriptor.License;
32 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
33 import org.apache.ivy.core.module.descriptor.WorkspaceModuleDescriptor;
34 import org.apache.ivy.core.module.id.ModuleId;
35 import org.apache.ivy.core.module.id.ModuleRevisionId;
36 import org.apache.ivy.core.report.DownloadStatus;
37 import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
38 import org.apache.ivy.core.resolve.ResolveData;
39 import org.apache.ivy.core.resolve.ResolvedModuleRevision;
40 import org.apache.ivy.osgi.core.BundleInfo;
41 import org.apache.ivy.osgi.core.ManifestHeaderElement;
42 import org.apache.ivy.osgi.core.ManifestHeaderValue;
43 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
44 import org.apache.ivy.plugins.version.VersionMatcher;
45 import org.apache.ivy.util.Message;
46
47 public abstract class AbstractWorkspaceResolver extends AbstractResolver {
48
49 private boolean ignoreBranch;
50
51 private boolean ignoreVersion;
52
53 public void setIgnoreBranch(boolean ignoreBranch) {
54 this.ignoreBranch = ignoreBranch;
55 }
56
57 public void setIgnoreVersion(boolean ignoreVersion) {
58 this.ignoreVersion = ignoreVersion;
59 }
60
61 protected ResolvedModuleRevision checkCandidate(DependencyDescriptor dd, ModuleDescriptor md,
62 String workspaceModuleName) {
63
64 if (workspaceModuleName == null) {
65 workspaceModuleName = dd.getDependencyId().toString();
66 }
67
68 ModuleRevisionId dependencyMrid = dd.getDependencyRevisionId();
69 String org = dependencyMrid.getModuleId().getOrganisation();
70 String module = dependencyMrid.getModuleId().getName();
71
72 VersionMatcher versionMatcher = getSettings().getVersionMatcher();
73
74 ModuleRevisionId candidateMrid = md.getModuleRevisionId();
75
76 // search a match on the organization and the module name
77
78 switch (org) {
79 case BundleInfo.BUNDLE_TYPE:
80 // looking for an OSGi bundle via its symbolic name
81 String sn = md.getExtraInfoContentByTagName("Bundle-SymbolicName");
82 if (sn == null || !module.equals(sn)) {
83 // not found, skip to next
84 return null;
85 }
86 break;
87 case BundleInfo.PACKAGE_TYPE:
88 // looking for an OSGi bundle via its exported package
89 String exportedPackages = md.getExtraInfoContentByTagName("Export-Package");
90 if (exportedPackages == null) {
91 // not found, skip to next
92 return null;
93 }
94 boolean found = false;
95 String version = null;
96 ManifestHeaderValue exportElements;
97 try {
98 exportElements = new ManifestHeaderValue(exportedPackages);
99 } catch (ParseException e) {
100 // wrong OSGi header: skip it
101 return null;
102 }
103 for (ManifestHeaderElement exportElement : exportElements.getElements()) {
104 if (exportElement.getValues().contains(module)) {
105 found = true;
106 version = exportElement.getAttributes().get("version");
107 break;
108 }
109 }
110 if (!found) {
111 // not found, skip to next
112 return null;
113 }
114 if (version == null) {
115 // no version means anything can match. Let's trick the version matcher by
116 // setting the exact expected version
117 version = dependencyMrid.getRevision();
118 }
119 md.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(org, module, version));
120 break;
121 default:
122 if (!candidateMrid.getModuleId().equals(dependencyMrid.getModuleId())) {
123 // it doesn't match org#module, skip to next
124 return null;
125 }
126 break;
127 }
128
129 Message.verbose("Workspace resolver found potential matching workspace module "
130 + workspaceModuleName + " with module " + candidateMrid + " for module "
131 + dependencyMrid);
132
133 if (!ignoreBranch) {
134 ModuleId mid = dependencyMrid.getModuleId();
135 String defaultBranch = getSettings().getDefaultBranch(mid);
136 String dependencyBranch = dependencyMrid.getBranch();
137 String candidateBranch = candidateMrid.getBranch();
138 if (dependencyBranch == null) {
139 dependencyBranch = defaultBranch;
140 }
141 if (candidateBranch == null) {
142 candidateBranch = defaultBranch;
143 }
144 if (dependencyBranch != candidateBranch) {
145 // Both cannot be null
146 if (dependencyBranch == null || candidateBranch == null) {
147 Message.verbose("\t\trejected since branches doesn't match (one is set, the other isn't)");
148 return null;
149 }
150 if (!dependencyBranch.equals(candidateBranch)) {
151 Message.verbose("\t\trejected since branches doesn't match");
152 return null;
153 }
154 }
155 }
156
157 // Found one; check if it is for the module we need
158 if (!ignoreVersion
159 && !md.getModuleRevisionId().getRevision().equals(Ivy.getWorkingRevision())
160 && !versionMatcher.accept(dd.getDependencyRevisionId(), md)) {
161 Message.verbose("\t\treject as version didn't match");
162 return null;
163 }
164
165 if (ignoreVersion) {
166 Message.verbose("\t\tmatched (version are ignored)");
167 } else {
168 Message.verbose("\t\tversion matched");
169 }
170
171 WorkspaceModuleDescriptor workspaceMd = createWorkspaceMd(md);
172
173 Artifact mdaf = md.getMetadataArtifact();
174 if (mdaf == null) {
175 mdaf = new DefaultArtifact(md.getModuleRevisionId(), md.getPublicationDate(),
176 workspaceModuleName, "ivy", "");
177 }
178 MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(mdaf);
179 madr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
180 madr.setSearched(true);
181
182 return new ResolvedModuleRevision(this, this, workspaceMd, madr);
183 }
184
185 protected WorkspaceModuleDescriptor createWorkspaceMd(ModuleDescriptor md) {
186 DefaultWorkspaceModuleDescriptor newMd = new DefaultWorkspaceModuleDescriptor(
187 md.getModuleRevisionId(), "release", null, true);
188 newMd.addConfiguration(new Configuration(ModuleDescriptor.DEFAULT_CONFIGURATION));
189 newMd.setLastModified(System.currentTimeMillis());
190
191 newMd.setDescription(md.getDescription());
192 newMd.setHomePage(md.getHomePage());
193 newMd.setLastModified(md.getLastModified());
194 newMd.setPublicationDate(md.getPublicationDate());
195 newMd.setResolvedPublicationDate(md.getResolvedPublicationDate());
196 newMd.setStatus(md.getStatus());
197
198 Configuration[] allConfs = md.getConfigurations();
199 for (Artifact af : createWorkspaceArtifacts(md)) {
200 if (allConfs.length == 0) {
201 newMd.addArtifact(ModuleDescriptor.DEFAULT_CONFIGURATION, af);
202 } else {
203 for (Configuration conf : allConfs) {
204 newMd.addConfiguration(conf);
205 newMd.addArtifact(conf.getName(), af);
206 }
207 }
208 }
209
210 for (DependencyDescriptor dependency : md.getDependencies()) {
211 newMd.addDependency(dependency);
212 }
213
214 for (ExcludeRule excludeRule : md.getAllExcludeRules()) {
215 newMd.addExcludeRule(excludeRule);
216 }
217
218 newMd.getExtraInfos().addAll(md.getExtraInfos());
219
220 for (License license : md.getLicenses()) {
221 newMd.addLicense(license);
222 }
223
224 return newMd;
225 }
226
227 protected abstract List<Artifact> createWorkspaceArtifacts(ModuleDescriptor md);
228
229 public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
230 throw new UnsupportedOperationException("publish not supported by " + getName());
231 }
232
233 public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
234 return null;
235 }
236
237 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030 import java.util.Collections;
3131 import java.util.Date;
3232 import java.util.HashMap;
33 import java.util.Iterator;
3433 import java.util.List;
3534 import java.util.ListIterator;
3635 import java.util.Map;
37 import java.util.Map.Entry;
3836
3937 import org.apache.ivy.core.IvyContext;
4038 import org.apache.ivy.core.IvyPatternHelper;
6058 import org.apache.ivy.core.search.OrganisationEntry;
6159 import org.apache.ivy.core.search.RevisionEntry;
6260 import org.apache.ivy.plugins.conflict.ConflictManager;
61 import org.apache.ivy.plugins.latest.ArtifactInfo;
6362 import org.apache.ivy.plugins.namespace.Namespace;
6463 import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
6564 import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
7776 import org.apache.ivy.plugins.version.VersionMatcher;
7877 import org.apache.ivy.util.Checks;
7978 import org.apache.ivy.util.ChecksumHelper;
79 import org.apache.ivy.util.DateUtil;
8080 import org.apache.ivy.util.HostUtil;
8181 import org.apache.ivy.util.Message;
82
83 import static org.apache.ivy.util.StringUtils.splitToArray;
8284
8385 /**
8486 *
9698 * </p>
9799 */
98100 private static class UnresolvedDependencyException extends RuntimeException {
101 private static final long serialVersionUID = 1L;
102
99103 private boolean error;
100104
101105 /**
126130 }
127131 }
128132
129 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss");
133 @Deprecated
134 public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
135 DateUtil.DATE_FORMAT_PATTERN);
130136
131137 private String workspaceName;
132138
137143 */
138144 private boolean envDependent = true;
139145
140 private List ivyattempts = new ArrayList();
141
142 private Map artattempts = new HashMap();
146 private List<String> ivyattempts = new ArrayList<>();
147
148 private Map<Artifact, List<String>> artattempts = new HashMap<>();
143149
144150 private boolean checkconsistency = true;
145151
178184 IvyContext context = IvyContext.pushNewCopyContext();
179185 try {
180186 ResolvedModuleRevision mr = data.getCurrentResolvedModuleRevision();
181 if (mr != null) {
182 if (shouldReturnResolvedModule(dd, mr)) {
183 return mr;
184 }
187 if (mr != null && shouldReturnResolvedModule(dd, mr)) {
188 return mr;
185189 }
186190
187191 if (isForce()) {
203207 boolean isDynamic = getAndCheckIsDynamic(systemMrid);
204208
205209 // we first search for the dependency in cache
206 ResolvedModuleRevision rmr = null;
207 rmr = findModuleInCache(systemDd, data);
210 ResolvedModuleRevision rmr = findModuleInCache(systemDd, data);
208211 if (rmr != null) {
209212 if (rmr.getDescriptor().isDefault() && rmr.getResolver() != this) {
210213 Message.verbose("\t" + getName() + ": found revision in cache: " + systemMrid
213216 } else if (isForce() && rmr.getResolver() != this) {
214217 Message.verbose("\t" + getName() + ": found revision in cache: " + systemMrid
215218 + " (resolved by " + rmr.getResolver().getName()
216 + "): but we are in force mode, let's try to find one ourself");
219 + "): but we are in force mode, let's try to find one ourselves");
217220 } else {
218221 Message.verbose("\t" + getName() + ": revision in cache: " + systemMrid);
219222 return checkLatest(systemDd, checkForcedResolvedModuleRevision(rmr), data);
237240 throw new UnresolvedDependencyException("\t" + getName()
238241 + ": no ivy file found for " + systemMrid, false);
239242 }
243
240244 nsMd = DefaultModuleDescriptor.newDefaultInstance(nsMrid,
241245 nsDd.getAllDependencyArtifacts());
242246 ResolvedResource artifactRef = findFirstArtifactRef(nsMd, nsDd, data);
243247 checkInterrupted();
248
244249 if (artifactRef == null) {
245250 throw new UnresolvedDependencyException("\t" + getName()
246251 + ": no ivy file nor artifact found for " + systemMrid, false);
247 } else {
248 long lastModified = artifactRef.getLastModified();
249 if (lastModified != 0 && nsMd instanceof DefaultModuleDescriptor) {
250 ((DefaultModuleDescriptor) nsMd).setLastModified(lastModified);
251 }
252 Message.verbose("\t" + getName() + ": no ivy file found for " + systemMrid
253 + ": using default data");
254 if (isDynamic) {
255 nsMd.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(nsMrid,
256 artifactRef.getRevision()));
257 }
258 systemMd = toSystem(nsMd);
259 MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(
260 systemMd.getMetadataArtifact());
261 madr.setDownloadStatus(DownloadStatus.NO);
262 madr.setSearched(true);
263 rmr = new ResolvedModuleRevision(this, this, systemMd, madr, isForce());
264 getRepositoryCacheManager().cacheModuleDescriptor(this, artifactRef,
265 toSystem(dd), systemMd.getAllArtifacts()[0], null, getCacheOptions(data));
266 }
252 }
253
254 long lastModified = artifactRef.getLastModified();
255 if (lastModified != 0 && nsMd instanceof DefaultModuleDescriptor) {
256 ((DefaultModuleDescriptor) nsMd).setLastModified(lastModified);
257 }
258 Message.verbose("\t" + getName() + ": no ivy file found for " + systemMrid
259 + ": using default data");
260 if (isDynamic) {
261 nsMd.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(nsMrid,
262 artifactRef.getRevision()));
263 }
264 systemMd = toSystem(nsMd);
265 MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(
266 systemMd.getMetadataArtifact());
267 madr.setDownloadStatus(DownloadStatus.NO);
268 madr.setSearched(true);
269 rmr = new ResolvedModuleRevision(this, this, systemMd, madr, isForce());
270 getRepositoryCacheManager().cacheModuleDescriptor(this, artifactRef,
271 toSystem(dd), systemMd.getAllArtifacts()[0], null, getCacheOptions(data));
267272 } else {
268273 if (ivyRef instanceof MDResolvedResource) {
269274 rmr = ((MDResolvedResource) ivyRef).getResolvedModuleRevision();
276281 }
277282 if (!rmr.getReport().isDownloaded() && rmr.getReport().getLocalFile() != null) {
278283 return checkLatest(systemDd, checkForcedResolvedModuleRevision(rmr), data);
284 }
285 nsMd = rmr.getDescriptor();
286
287 // check descriptor data is in sync with resource revision and names
288 systemMd = toSystem(nsMd);
289 if (isCheckconsistency()) {
290 checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
291 checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
279292 } else {
280 nsMd = rmr.getDescriptor();
281
282 // check descriptor data is in sync with resource revision and names
283 systemMd = toSystem(nsMd);
284 if (isCheckconsistency()) {
293 if (systemMd instanceof DefaultModuleDescriptor) {
294 DefaultModuleDescriptor defaultMd = (DefaultModuleDescriptor) systemMd;
295 ModuleRevisionId revision = getRevision(ivyRef, systemMrid, systemMd);
296 defaultMd.setModuleRevisionId(revision);
297 defaultMd.setResolvedModuleRevisionId(revision);
298 } else {
299 Message.warn(
300 "consistency disabled with instance of non DefaultModuleDescriptor... module info can't be updated, so consistency check will be done");
301 checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
285302 checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
286 checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
287 } else {
288 if (systemMd instanceof DefaultModuleDescriptor) {
289 DefaultModuleDescriptor defaultMd = (DefaultModuleDescriptor) systemMd;
290 ModuleRevisionId revision = getRevision(ivyRef, systemMrid, systemMd);
291 defaultMd.setModuleRevisionId(revision);
292 defaultMd.setResolvedModuleRevisionId(revision);
293 } else {
294 Message.warn("consistency disabled with instance of non DefaultModuleDescriptor..."
295 + " module info can't be updated, so consistency check will be done");
296 checkDescriptorConsistency(nsMrid, nsMd, ivyRef);
297 checkDescriptorConsistency(systemMrid, systemMd, ivyRef);
298 }
299303 }
300 rmr = new ResolvedModuleRevision(this, this, systemMd,
301 toSystem(rmr.getReport()), isForce());
302 }
304 }
305 rmr = new ResolvedModuleRevision(this, this, systemMd,
306 toSystem(rmr.getReport()), isForce());
303307 }
304308
305309 resolveAndCheckRevision(systemMd, systemMrid, ivyRef, isDynamic);
312316
313317 return checkLatest(systemDd, checkForcedResolvedModuleRevision(rmr), data);
314318 } catch (UnresolvedDependencyException ex) {
315 if (ex.getMessage().length() > 0) {
319 if (!ex.getMessage().isEmpty()) {
316320 if (ex.isError()) {
317321 Message.error(ex.getMessage());
318322 } else {
356360 final ModuleDescriptorParser parser = systemMd.getParser();
357361
358362 // the metadata artifact which was used to cache the original metadata file
359 Artifact requestedMetadataArtifact = ivyRef == null ? systemMd.getMetadataArtifact()
363 Artifact requestedMetadataArtifact = (ivyRef == null) ? systemMd.getMetadataArtifact()
360364 : parser.getMetadataArtifact(
361 ModuleRevisionId.newInstance(systemMrid, systemMd.getRevision()),
362 ivyRef.getResource());
365 ModuleRevisionId.newInstance(systemMrid, systemMd.getRevision()),
366 ivyRef.getResource());
363367
364368 cacheManager.originalToCachedModuleDescriptor(this, ivyRef, requestedMetadataArtifact, rmr,
365369 new ModuleDescriptorWriter() {
389393 DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) systemMd;
390394 if (dmd.isNamespaceUseful()) {
391395 Message.warn("the module descriptor " + ivyRef.getResource()
392 + " has information which can't be converted into "
393 + "the system namespace. "
394 + "It will require the availability of the namespace '"
396 + " has information which can't be converted into the system namespace. It will require the availability of the namespace '"
395397 + getNamespace().getName() + "' to be fully usable.");
396398 }
397399 }
399401
400402 private void resolveAndCheckPublicationDate(DependencyDescriptor systemDd,
401403 ModuleDescriptor systemMd, ModuleRevisionId systemMrid, ResolveData data) {
404 if (data.getDate() == null) {
405 return;
406 }
402407 // resolve and check publication date
403 if (data.getDate() != null) {
404 long pubDate = getPublicationDate(systemMd, systemDd, data);
405 if (pubDate > data.getDate().getTime()) {
406 throw new UnresolvedDependencyException("\t" + getName()
407 + ": unacceptable publication date => was=" + new Date(pubDate)
408 + " required=" + data.getDate());
409 } else if (pubDate == -1) {
410 throw new UnresolvedDependencyException("\t" + getName()
411 + ": impossible to guess publication date: artifact missing for "
412 + systemMrid);
413 }
414 systemMd.setResolvedPublicationDate(new Date(pubDate));
415 }
408 long pubDate = getPublicationDate(systemMd, systemDd, data);
409 if (pubDate > data.getDate().getTime()) {
410 throw new UnresolvedDependencyException("\t" + getName()
411 + ": unacceptable publication date => was=" + new Date(pubDate)
412 + " required=" + data.getDate());
413 }
414 if (pubDate == -1) {
415 throw new UnresolvedDependencyException("\t" + getName()
416 + ": impossible to guess publication date: artifact missing for "
417 + systemMrid);
418 }
419 systemMd.setResolvedPublicationDate(new Date(pubDate));
416420 }
417421
418422 protected void checkModuleDescriptorRevision(ModuleDescriptor systemMd,
436440
437441 private void checkRevision(ModuleRevisionId systemMrid) {
438442 // check revision
439 int index = systemMrid.getRevision().indexOf("@");
443 int index = systemMrid.getRevision().indexOf('@');
440444 if (index != -1 && !systemMrid.getRevision().substring(index + 1).equals(workspaceName)) {
441445 throw new UnresolvedDependencyException("\t" + getName() + ": unhandled revision => "
442446 + systemMrid.getRevision());
470474 }
471475
472476 private ModuleRevisionId getRevision(ResolvedResource ivyRef, ModuleRevisionId askedMrid,
473 ModuleDescriptor md) throws ParseException {
474 Map allAttributes = new HashMap();
477 ModuleDescriptor md) {
478 Map<String, String> allAttributes = new HashMap<>();
475479 allAttributes.putAll(md.getQualifiedExtraAttributes());
476480 allAttributes.putAll(askedMrid.getQualifiedExtraAttributes());
477481
520524 IvyNode node = data.getNode(resolvedMrid);
521525 if (node != null && node.getModuleRevision() != null) {
522526 // this revision has already be resolved : return it
523 if (node.getDescriptor() != null && node.getDescriptor().isDefault()) {
524 Message.verbose("\t" + getName() + ": found already resolved revision: "
525 + resolvedMrid
526 + ": but it's a default one, maybe we can find a better one");
527 } else {
527 if (node.getDescriptor() == null || !node.getDescriptor().isDefault()) {
528528 Message.verbose("\t" + getName() + ": revision already resolved: "
529529 + resolvedMrid);
530530 node.getModuleRevision().getReport().setSearched(true);
531531 return node.getModuleRevision();
532532 }
533 Message.verbose("\t" + getName() + ": found already resolved revision: "
534 + resolvedMrid
535 + ": but it's a default one, maybe we can find a better one");
533536 }
534537 }
535538
544547 try {
545548 ResolvedModuleRevision rmr = BasicResolver.this.parse(new ResolvedResource(
546549 resource, rev), dd, data);
547 if (rmr == null) {
548 return null;
549 } else {
550 if (rmr != null) {
550551 return new MDResolvedResource(resource, rev, rmr);
551552 }
552553 } catch (ParseException e) {
553554 Message.warn("Failed to parse the file '" + resource + "'", e);
554 return null;
555 }
555 }
556 return null;
556557 }
557558
558559 };
581582 private void checkDescriptorConsistency(ModuleRevisionId mrid, ModuleDescriptor md,
582583 ResolvedResource ivyRef) throws ParseException {
583584 boolean ok = true;
584 StringBuffer errors = new StringBuffer();
585 StringBuilder errors = new StringBuilder();
585586 if (!mrid.getOrganisation().equals(md.getModuleRevisionId().getOrganisation())) {
586 Message.error("\t" + getName() + ": bad organisation found in " + ivyRef.getResource()
587 + ": expected='" + mrid.getOrganisation() + "' found='"
588 + md.getModuleRevisionId().getOrganisation() + "'");
589 errors.append("bad organisation: expected='" + mrid.getOrganisation() + "' found='"
590 + md.getModuleRevisionId().getOrganisation() + "'; ");
587 Message.error(String.format("\t%s: bad organisation found in %s: expected='%s' found='%s'",
588 getName(), ivyRef.getResource(), mrid.getOrganisation(),
589 md.getModuleRevisionId().getOrganisation()));
590 errors.append("bad organisation: expected='").append(mrid.getOrganisation())
591 .append("' found='").append(md.getModuleRevisionId().getOrganisation()).append("'; ");
591592 ok = false;
592593 }
593594 if (!mrid.getName().equals(md.getModuleRevisionId().getName())) {
594 Message.error("\t" + getName() + ": bad module name found in " + ivyRef.getResource()
595 + ": expected='" + mrid.getName() + " found='"
596 + md.getModuleRevisionId().getName() + "'");
597 errors.append("bad module name: expected='" + mrid.getName() + "' found='"
598 + md.getModuleRevisionId().getName() + "'; ");
595 Message.error(String.format("\t%s: bad module name found in %s: expected='%s found='%s'",
596 getName(), ivyRef.getResource(), mrid.getName(),
597 md.getModuleRevisionId().getName()));
598 errors.append("bad module name: expected='").append(mrid.getName()).append("' found='")
599 .append(md.getModuleRevisionId().getName()).append("'; ");
599600 ok = false;
600601 }
601602 if (mrid.getBranch() != null
602603 && !mrid.getBranch().equals(md.getModuleRevisionId().getBranch())) {
603 Message.error("\t" + getName() + ": bad branch name found in " + ivyRef.getResource()
604 + ": expected='" + mrid.getBranch() + " found='"
605 + md.getModuleRevisionId().getBranch() + "'");
606 errors.append("bad branch name: expected='" + mrid.getBranch() + "' found='"
607 + md.getModuleRevisionId().getBranch() + "'; ");
604 Message.error(String.format("\t%s: bad branch name found in %s: expected='%s found='%s'",
605 getName(), ivyRef.getResource(), mrid.getBranch(),
606 md.getModuleRevisionId().getBranch()));
607 errors.append("bad branch name: expected='").append(mrid.getBranch()).append("' found='")
608 .append(md.getModuleRevisionId().getBranch()).append("'; ");
608609 ok = false;
609610 }
610611 if (ivyRef.getRevision() != null && !ivyRef.getRevision().startsWith("working@")
611612 && !mrid.getRevision().equals(md.getModuleRevisionId().getRevision())) {
612613 ModuleRevisionId expectedMrid = ModuleRevisionId.newInstance(mrid, mrid.getRevision());
613614 if (!getSettings().getVersionMatcher().accept(expectedMrid, md)) {
614 Message.error("\t" + getName() + ": bad revision found in " + ivyRef.getResource()
615 + ": expected='" + ivyRef.getRevision() + " found='"
616 + md.getModuleRevisionId().getRevision() + "'");
617 errors.append("bad revision: expected='" + ivyRef.getRevision() + "' found='"
618 + md.getModuleRevisionId().getRevision() + "'; ");
615 Message.error(String.format("\t%s: bad revision found in %s: expected='%s found='%s'",
616 getName(), ivyRef.getResource(), ivyRef.getRevision(),
617 md.getModuleRevisionId().getRevision()));
618 errors.append("bad revision: expected='").append(ivyRef.getRevision())
619 .append("' found='").append(md.getModuleRevisionId().getRevision()).append("'; ");
619620 ok = false;
620621 }
621622 }
622623 if (!getSettings().getStatusManager().isStatus(md.getStatus())) {
623 Message.error("\t" + getName() + ": bad status found in " + ivyRef.getResource()
624 + ": '" + md.getStatus() + "'");
625 errors.append("bad status: '" + md.getStatus() + "'; ");
624 Message.error(String.format("\t%s: bad status found in %s: '%s'",
625 getName(), ivyRef.getResource(), md.getStatus()));
626 errors.append("bad status: '").append(md.getStatus()).append("'; ");
626627 ok = false;
627628 }
628 for (Iterator it = mrid.getExtraAttributes().entrySet().iterator(); it.hasNext();) {
629 Entry extra = (Entry) it.next();
629 for (Map.Entry<String, String> extra : mrid.getExtraAttributes().entrySet()) {
630630 if (extra.getValue() != null
631 && !extra.getValue().equals(md.getExtraAttribute((String) extra.getKey()))) {
632 String errorMsg = "bad " + extra.getKey() + " found in " + ivyRef.getResource()
633 + ": expected='" + extra.getValue() + "' found='"
634 + md.getExtraAttribute((String) extra.getKey()) + "'";
631 && !extra.getValue().equals(md.getExtraAttribute(extra.getKey()))) {
632 String errorMsg = String.format("bad %s found in %s: expected='%s' found='%s'",
633 extra.getKey(), ivyRef.getResource(), extra.getValue(),
634 md.getExtraAttribute(extra.getKey()));
635635 Message.error("\t" + getName() + ": " + errorMsg);
636 errors.append(errorMsg + ";");
636 errors.append(errorMsg).append(";");
637637 ok = false;
638638 }
639639 }
645645
646646 /**
647647 * When the resolver has many choices, this function helps choosing one
648 *
648 *
649649 * @param rress
650650 * the list of resolved resource which the resolver found to fit the requirement
651651 * @param rmdparser
662662 VersionMatcher versionMatcher = getSettings().getVersionMatcher();
663663
664664 ResolvedResource found = null;
665 List sorted = getLatestStrategy().sort(rress);
666 List rejected = new ArrayList();
667 List foundBlacklisted = new ArrayList();
665 List<ArtifactInfo> sorted = getLatestStrategy().sort(rress);
666 List<String> rejected = new ArrayList<>();
667 List<ModuleRevisionId> foundBlacklisted = new ArrayList<>();
668668 IvyContext context = IvyContext.getContext();
669669
670 for (ListIterator iter = sorted.listIterator(sorted.size()); iter.hasPrevious();) {
670 ListIterator<ArtifactInfo> iter = sorted.listIterator(sorted.size());
671 while (iter.hasPrevious()) {
671672 ResolvedResource rres = (ResolvedResource) iter.previous();
672673 // we start by filtering based on information already available,
673674 // even though we don't even know if the resource actually exist.
674675 // But checking for existence is most of the time more costly than checking
675676 // name, blacklisting and first level version matching
676 if (filterNames(new ArrayList(Collections.singleton(rres.getRevision()))).isEmpty()) {
677 if (filterNames(new ArrayList<>(Collections.singleton(rres.getRevision())))
678 .isEmpty()) {
677679 Message.debug("\t" + name + ": filtered by name: " + rres);
678680 continue;
679681 }
699701 rejected.add(rres.getRevision() + " (unreachable)");
700702 continue;
701703 }
702 if ((date != null && rres.getLastModified() > date.getTime())) {
704 if (date != null && rres.getLastModified() > date.getTime()) {
703705 Message.verbose("\t" + name + ": too young: " + rres);
704706 rejected.add(rres.getRevision() + " (" + rres.getLastModified() + ")");
705707 continue;
706708 }
707709 if (versionMatcher.needModuleDescriptor(mrid, foundMrid)) {
708 ResolvedResource r = rmdparser.parse(rres.getResource(), rres.getRevision());
710 MDResolvedResource r = rmdparser.parse(rres.getResource(), rres.getRevision());
709711 if (r == null) {
710712 Message.debug("\t" + name + ": impossible to get module descriptor resource: "
711713 + rres);
712714 rejected.add(rres.getRevision() + " (no or bad MD)");
713715 continue;
714716 }
715 ModuleDescriptor md = ((MDResolvedResource) r).getResolvedModuleRevision()
716 .getDescriptor();
717 ModuleDescriptor md = r.getResolvedModuleRevision().getDescriptor();
717718 if (md.isDefault()) {
718719 Message.debug("\t" + name + ": default md rejected by version matcher"
719720 + "requiring module descriptor: " + rres);
720721 rejected.add(rres.getRevision() + " (MD)");
721722 continue;
722 } else if (!versionMatcher.accept(mrid, md)) {
723 }
724 if (!versionMatcher.accept(mrid, md)) {
723725 Message.debug("\t" + name + ": md rejected by version matcher: " + rres);
724726 rejected.add(rres.getRevision() + " (MD)");
725727 continue;
726 } else {
727 found = r;
728 }
728 }
729 found = r;
729730 } else {
730731 found = rres;
731732 }
754755 * <p>
755756 * Remember to call the super implementation when overriding this method.
756757 * </p>
757 *
758 *
758759 * @param names
759760 * the list to filter.
760761 * @return the filtered list
761762 */
762 protected Collection filterNames(Collection names) {
763 protected Collection<String> filterNames(Collection<String> names) {
763764 getSettings().filterIgnore(names);
764765 return names;
765766 }
775776 }
776777
777778 protected void logArtifactAttempt(Artifact art, String attempt) {
778 List attempts = (List) artattempts.get(art);
779 List<String> attempts = artattempts.get(art);
779780 if (attempts == null) {
780 attempts = new ArrayList();
781 attempts = new ArrayList<>();
781782 artattempts.put(art, attempts);
782783 }
783784 attempts.add(attempt);
785786 }
786787
787788 protected void logAttempt(String attempt) {
788 Artifact currentArtifact = (Artifact) IvyContext.getContext().get(getName() + ".artifact");
789 if (currentArtifact != null) {
789 Artifact currentArtifact = IvyContext.getContext().get(getName() + ".artifact");
790 if (currentArtifact == null) {
791 logIvyAttempt(attempt);
792 } else {
790793 logArtifactAttempt(currentArtifact, attempt);
791 } else {
792 logIvyAttempt(attempt);
793 }
794 }
795
794 }
795 }
796
797 @Override
796798 public void reportFailure() {
797799 Message.warn("==== " + getName() + ": tried");
798 for (ListIterator iter = ivyattempts.listIterator(); iter.hasNext();) {
799 String m = (String) iter.next();
800 for (String m : ivyattempts) {
800801 Message.warn(" " + m);
801802 }
802 for (Iterator iter = artattempts.keySet().iterator(); iter.hasNext();) {
803 Artifact art = (Artifact) iter.next();
804 List attempts = (List) artattempts.get(art);
803 for (Map.Entry<Artifact, List<String>> entry : artattempts.entrySet()) {
804 List<String> attempts = entry.getValue();
805805 if (attempts != null) {
806 Message.warn(" -- artifact " + art + ":");
807 for (ListIterator iterator = attempts.listIterator(); iterator.hasNext();) {
808 String m = (String) iterator.next();
806 Message.warn(" -- artifact " + entry.getKey() + ":");
807 for (String m : attempts) {
809808 Message.warn(" " + m);
810809 }
811810 }
812811 }
813812 }
814813
814 @Override
815815 public void reportFailure(Artifact art) {
816816 Message.warn("==== " + getName() + ": tried");
817 List attempts = (List) artattempts.get(art);
817 List<String> attempts = artattempts.get(art);
818818 if (attempts != null) {
819 for (ListIterator iter = attempts.listIterator(); iter.hasNext();) {
820 String m = (String) iter.next();
819 for (String m : attempts) {
821820 Message.warn(" " + m);
822821 }
823822 }
832831
833832 clearArtifactAttempts();
834833 DownloadReport dr = new DownloadReport();
835 for (int i = 0; i < artifacts.length; i++) {
836 ArtifactDownloadReport adr = cacheManager.download(artifacts[i],
837 artifactResourceResolver, downloader, getCacheDownloadOptions(options));
834 for (Artifact artifact : artifacts) {
835 ArtifactDownloadReport adr = cacheManager.download(artifact, artifactResourceResolver,
836 downloader, getCacheDownloadOptions(options));
838837 if (DownloadStatus.FAILED == adr.getDownloadStatus()) {
839838 if (!ArtifactDownloadReport.MISSING_ARTIFACT.equals(adr.getDownloadDetails())) {
840839 Message.warn("\t" + adr);
856855 artattempts.clear();
857856 }
858857
858 @Override
859859 public ArtifactDownloadReport download(final ArtifactOrigin origin, DownloadOptions options) {
860860 Checks.checkNotNull(origin, "origin");
861861 return getRepositoryCacheManager().download(origin.getArtifact(),
863863 public ResolvedResource resolve(Artifact artifact) {
864864 try {
865865 Resource resource = getResource(origin.getLocation());
866 if (resource == null) {
867 return null;
866 if (resource != null) {
867 String revision = origin.getArtifact().getModuleRevisionId().getRevision();
868 return new ResolvedResource(resource, revision);
868869 }
869 String revision = origin.getArtifact().getModuleRevisionId().getRevision();
870 return new ResolvedResource(resource, revision);
871870 } catch (IOException e) {
872871 Message.debug(e);
873 return null;
874872 }
873 return null;
875874 }
876875 }, downloader, getCacheDownloadOptions(options));
877876 }
878877
879878 protected abstract Resource getResource(String source) throws IOException;
880879
880 @Override
881881 public boolean exists(Artifact artifact) {
882882 ResolvedResource artifactRef = getArtifactRef(artifact, null);
883 if (artifactRef != null) {
884 return artifactRef.getResource().exists();
885 }
886 return false;
887 }
888
883 return artifactRef != null && artifactRef.getResource().exists();
884 }
885
886 @Override
889887 public ArtifactOrigin locate(Artifact artifact) {
890888 ArtifactOrigin origin = getRepositoryCacheManager().getSavedArtifactOrigin(
891889 toSystem(artifact));
911909 return -1;
912910 }
913911
912 @Override
914913 public String toString() {
915914 return getName();
916915 }
917916
918 public String[] listTokenValues(String token, Map otherTokenValues) {
919 Collection ret = findNames(otherTokenValues, token);
920 return (String[]) ret.toArray(new String[ret.size()]);
921 }
922
917 @Override
918 public String[] listTokenValues(String token, Map<String, String> otherTokenValues) {
919 Collection<String> ret = findNames(otherTokenValues, token);
920 return ret.toArray(new String[ret.size()]);
921 }
922
923 @Override
923924 public OrganisationEntry[] listOrganisations() {
924 Collection names = findNames(Collections.EMPTY_MAP, IvyPatternHelper.ORGANISATION_KEY);
925 OrganisationEntry[] ret = new OrganisationEntry[names.size()];
926 int i = 0;
927 for (Iterator iter = names.iterator(); iter.hasNext(); i++) {
928 String org = (String) iter.next();
929 ret[i] = new OrganisationEntry(this, org);
930 }
931 return ret;
932 }
933
925 Collection<String> names = findNames(Collections.<String, String> emptyMap(),
926 IvyPatternHelper.ORGANISATION_KEY);
927 List<OrganisationEntry> ret = new ArrayList<>(names.size());
928 for (String org : names) {
929 ret.add(new OrganisationEntry(this, org));
930 }
931 return ret.toArray(new OrganisationEntry[names.size()]);
932 }
933
934 @Override
934935 public ModuleEntry[] listModules(OrganisationEntry org) {
935 Map tokenValues = new HashMap();
936 Map<String, String> tokenValues = new HashMap<>();
936937 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org.getOrganisation());
937 Collection names = findNames(tokenValues, IvyPatternHelper.MODULE_KEY);
938 ModuleEntry[] ret = new ModuleEntry[names.size()];
939 int i = 0;
940 for (Iterator iter = names.iterator(); iter.hasNext(); i++) {
941 String name = (String) iter.next();
942 ret[i] = new ModuleEntry(org, name);
943 }
944 return ret;
945 }
946
938 Collection<String> names = findNames(tokenValues, IvyPatternHelper.MODULE_KEY);
939 List<ModuleEntry> ret = new ArrayList<>(names.size());
940 for (String name : names) {
941 ret.add(new ModuleEntry(org, name));
942 }
943 return ret.toArray(new ModuleEntry[names.size()]);
944 }
945
946 @Override
947947 public RevisionEntry[] listRevisions(ModuleEntry mod) {
948 Map tokenValues = new HashMap();
948 Map<String, String> tokenValues = new HashMap<>();
949949 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, mod.getOrganisation());
950950 tokenValues.put(IvyPatternHelper.MODULE_KEY, mod.getModule());
951 Collection names = findNames(tokenValues, IvyPatternHelper.REVISION_KEY);
952 RevisionEntry[] ret = new RevisionEntry[names.size()];
953 int i = 0;
954 for (Iterator iter = names.iterator(); iter.hasNext(); i++) {
955 String name = (String) iter.next();
956 ret[i] = new RevisionEntry(mod, name);
957 }
958 return ret;
959 }
960
961 protected abstract Collection findNames(Map tokenValues, String token);
951 Collection<String> names = findNames(tokenValues, IvyPatternHelper.REVISION_KEY);
952 List<RevisionEntry> ret = new ArrayList<>(names.size());
953 for (String name : names) {
954 ret.add(new RevisionEntry(mod, name));
955 }
956 return ret.toArray(new RevisionEntry[names.size()]);
957 }
958
959 protected abstract Collection<String> findNames(Map<String, String> tokenValues, String token);
962960
963961 protected ResolvedResource findFirstArtifactRef(ModuleDescriptor md, DependencyDescriptor dd,
964962 ResolveData data) {
965 ResolvedResource ret = null;
966 String[] conf = md.getConfigurationsNames();
967 for (int i = 0; i < conf.length; i++) {
968 Artifact[] artifacts = md.getArtifacts(conf[i]);
969 for (int j = 0; j < artifacts.length; j++) {
970 ret = getArtifactRef(artifacts[j], data.getDate());
963 for (String configName : md.getConfigurationsNames()) {
964 for (Artifact artifact : md.getArtifacts(configName)) {
965 ResolvedResource ret = getArtifactRef(artifact, data.getDate());
971966 if (ret != null) {
972967 return ret;
973968 }
978973
979974 protected long getAndCheck(Resource resource, File dest) throws IOException {
980975 long size = get(resource, dest);
981 String[] checksums = getChecksumAlgorithms();
982 boolean checked = false;
983 for (int i = 0; i < checksums.length && !checked; i++) {
984 checked = check(resource, dest, checksums[i]);
976 for (String checksum : getChecksumAlgorithms()) {
977 if (check(resource, dest, checksum)) {
978 break;
979 }
985980 }
986981 return size;
987982 }
988983
989984 /**
990985 * Checks the given resource checksum if a checksum resource exists.
991 *
986 *
992987 * @param resource
993988 * the resource to check
994989 * @param dest
10461041 }
10471042 resource = new FileResource(new FileRepository(), f);
10481043 } else {
1049 resource = new URLResource(url);
1044 resource = new URLResource(url, this.getTimeoutConstraint());
10501045 }
10511046 ret = new ResolvedResource(resource, artifact.getModuleRevisionId().getRevision());
10521047 }
10681063 return checkconsistency;
10691064 }
10701065
1071 public void setCheckconsistency(boolean checkConsitency) {
1072 checkconsistency = checkConsitency;
1066 public void setCheckconsistency(boolean checkConsistency) {
1067 checkconsistency = checkConsistency;
10731068 }
10741069
10751070 public void setForce(boolean force) {
10931088 /**
10941089 * Sets the module descriptor presence rule. Should be one of {@link #DESCRIPTOR_REQUIRED} or
10951090 * {@link #DESCRIPTOR_OPTIONAL}.
1096 *
1091 *
10971092 * @param descriptorRule
10981093 * the descriptor rule to use with this resolver.
10991094 */
11001095 public void setDescriptor(String descriptorRule) {
1101 if (DESCRIPTOR_REQUIRED.equals(descriptorRule)) {
1102 allownomd = false;
1103 } else if (DESCRIPTOR_OPTIONAL.equals(descriptorRule)) {
1104 allownomd = true;
1105 } else {
1106 throw new IllegalArgumentException("unknown descriptor rule '" + descriptorRule
1107 + "'. Allowed rules are: "
1108 + Arrays.asList(new String[] {DESCRIPTOR_REQUIRED, DESCRIPTOR_OPTIONAL}));
1096 switch (descriptorRule) {
1097 case DESCRIPTOR_REQUIRED:
1098 allownomd = false;
1099 break;
1100 case DESCRIPTOR_OPTIONAL:
1101 allownomd = true;
1102 break;
1103 default:
1104 throw new IllegalArgumentException("unknown descriptor rule '" + descriptorRule
1105 + "'. Allowed rules are: "
1106 + Arrays.asList(DESCRIPTOR_REQUIRED, DESCRIPTOR_OPTIONAL));
11091107 }
11101108 }
11111109
11121110 public String[] getChecksumAlgorithms() {
1113 String csDef = checksums == null ? getSettings().getVariable("ivy.checksums") : checksums;
1111 String csDef = (checksums == null) ? getSettings().getVariable("ivy.checksums") : checksums;
11141112 if (csDef == null) {
11151113 return new String[0];
11161114 }
11171115 // csDef is a comma separated list of checksum algorithms to use with this resolver
11181116 // we parse and return it as a String[]
1119 String[] checksums = csDef.split(",");
1120 List algos = new ArrayList();
1121 for (int i = 0; i < checksums.length; i++) {
1122 String cs = checksums[i].trim();
1123 if (!"".equals(cs) && !"none".equals(cs)) {
1117 List<String> algos = new ArrayList<>();
1118 for (String cs : splitToArray(csDef)) {
1119 if (!cs.isEmpty() && !"none".equals(cs)) {
11241120 algos.add(cs);
11251121 }
11261122 }
1127 return (String[]) algos.toArray(new String[algos.size()]);
1123 return algos.toArray(new String[algos.size()]);
11281124 }
11291125
11301126 public void setChecksums(String checksums) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.plugins.resolver;
1818
19 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
20
1921 /**
2022 * BintrayResolver is a resolver which can be used to resolve dependencies found in the Bintray
2123 * artifacts repository.
2224 */
23 @SuppressWarnings("ClassTooDeepInInheritanceTree")
2425 public class BintrayResolver extends IBiblioResolver {
2526
2627 private static final String JCENTER = "https://jcenter.bintray.com/";
5455 updateRoot();
5556 }
5657
57 @SuppressWarnings("MethodWithMultipleReturnPoints")
5858 private void updateRoot() {
59 if (isEmpty(subject) || isEmpty(repo)) {
59 if (isNullOrEmpty(subject) || isNullOrEmpty(repo)) {
6060 return;
6161 }
6262
6565 }
6666
6767 private void updateName(String defaultName) {
68 if (isEmpty(defaultName)) {
68 if (isNullOrEmpty(defaultName)) {
6969 throw new IllegalArgumentException("Default resolver name must not be null or empty");
7070 }
71 if (isEmpty(getName()) || isNameUpdatable) {
71 if (isNullOrEmpty(getName()) || isNameUpdatable) {
7272 isNameUpdatable = true;
7373 setName(defaultName);
7474 }
7575 }
76
77 private boolean isEmpty(String s) {
78 return ((s == null) || (s.trim().length() < 1));
79 }
8076 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4141 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
4242 import org.apache.ivy.util.Message;
4343
44 @Deprecated
4445 public class CacheResolver extends FileSystemResolver {
4546 public CacheResolver() {
4647 }
5051 setName("cache");
5152 }
5253
54 @Override
5355 public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
5456 throws ParseException {
5557 clearIvyAttempts();
100102 }
101103 }
102104
105 @Override
103106 public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
104107 ensureConfigured();
105108 clearArtifactAttempts();
106109 DownloadReport dr = new DownloadReport();
107 for (int i = 0; i < artifacts.length; i++) {
108 final ArtifactDownloadReport adr = new ArtifactDownloadReport(artifacts[i]);
110 for (Artifact artifact : artifacts) {
111 final ArtifactDownloadReport adr = new ArtifactDownloadReport(artifact);
109112 dr.addArtifactReport(adr);
110 ResolvedResource artifactRef = getArtifactRef(artifacts[i], null);
113 ResolvedResource artifactRef = getArtifactRef(artifact, null);
111114 if (artifactRef != null) {
112 Message.verbose("\t[NOT REQUIRED] " + artifacts[i]);
113 ArtifactOrigin origin = new ArtifactOrigin(artifacts[i], true, artifactRef
115 Message.verbose("\t[NOT REQUIRED] " + artifact);
116 ArtifactOrigin origin = new ArtifactOrigin(artifact, true, artifactRef
114117 .getResource().getName());
115118 File archiveFile = ((FileResource) artifactRef.getResource()).getFile();
116119 adr.setDownloadStatus(DownloadStatus.NO);
124127 return dr;
125128 }
126129
130 @Override
127131 public boolean exists(Artifact artifact) {
128132 ensureConfigured();
129133 return super.exists(artifact);
130134 }
131135
136 @Override
132137 public ArtifactOrigin locate(Artifact artifact) {
133138 ensureConfigured();
134139 return super.locate(artifact);
135140 }
136141
142 @Override
137143 public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
138144 ensureConfigured();
139145 super.publish(artifact, src, overwrite);
140146 }
141147
148 @Override
142149 public OrganisationEntry[] listOrganisations() {
143150 ensureConfigured();
144151 return super.listOrganisations();
145152 }
146153
154 @Override
147155 public ModuleEntry[] listModules(OrganisationEntry org) {
148156 ensureConfigured();
149157 return super.listModules(org);
150158 }
151159
160 @Override
152161 public RevisionEntry[] listRevisions(ModuleEntry module) {
153162 ensureConfigured();
154163 return super.listRevisions(module);
155164 }
156165
166 @Override
157167 public void dumpSettings() {
158168 Message.verbose("\t" + getName() + " [cache]");
159169 }
160170
161171 private void ensureConfigured() {
162172 if (getIvyPatterns().isEmpty()) {
163 setIvyPatterns(new ArrayList());
164 setArtifactPatterns(new ArrayList());
165 RepositoryCacheManager[] caches = getSettings().getRepositoryCacheManagers();
166 for (int i = 0; i < caches.length; i++) {
167 if (caches[i] instanceof DefaultRepositoryCacheManager) {
168 DefaultRepositoryCacheManager c = (DefaultRepositoryCacheManager) caches[i];
173 setIvyPatterns(new ArrayList<String>());
174 setArtifactPatterns(new ArrayList<String>());
175 for (RepositoryCacheManager cache : getSettings().getRepositoryCacheManagers()) {
176 if (cache instanceof DefaultRepositoryCacheManager) {
177 DefaultRepositoryCacheManager c = (DefaultRepositoryCacheManager) cache;
169178 addIvyPattern(c.getBasedir().getAbsolutePath() + "/" + c.getIvyPattern());
170179 addArtifactPattern(c.getBasedir().getAbsolutePath() + "/"
171180 + c.getArtifactPattern());
172181 } else {
173 Message.verbose(caches[i]
182 Message.verbose(cache
174183 + ": cache implementation is not a DefaultRepositoryCacheManager:"
175184 + " unable to configure cache resolver with it");
176185 }
178187 }
179188 }
180189
190 @Override
181191 public String getTypeName() {
182192 return "cache";
183193 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.util.Arrays;
2424 import java.util.HashMap;
2525 import java.util.HashSet;
26 import java.util.Iterator;
2726 import java.util.List;
2827 import java.util.Map;
2928 import java.util.Set;
6362 public long getLastModified() {
6463 return rmr.getPublicationDate().getTime();
6564 }
66
6765 }
6866
6967 private boolean returnFirst = false;
7068
71 private List chain = new ArrayList();
69 private List<DependencyResolver> chain = new ArrayList<>();
7270
7371 private boolean dual;
7472
8078 throws ParseException {
8179 data = new ResolveData(data, doValidate(data));
8280
83 List errors = new ArrayList();
81 List<Exception> errors = new ArrayList<>();
8482
8583 ResolvedModuleRevision resolved = data.getCurrentResolvedModuleRevision();
8684 ResolvedModuleRevision mr = resolved;
9492 }
9593 }
9694
97 for (Iterator iter = chain.iterator(); iter.hasNext();) {
98 DependencyResolver resolver = (DependencyResolver) iter.next();
95 for (DependencyResolver resolver : chain) {
9996 LatestStrategy oldLatest = setLatestIfRequired(resolver, getLatestStrategy());
10097 try {
10198 ResolvedModuleRevision previouslyResolved = mr;
116113 }
117114 if (mr == null && !errors.isEmpty()) {
118115 if (errors.size() == 1) {
119 Exception ex = (Exception) errors.get(0);
116 Exception ex = errors.get(0);
120117 if (ex instanceof RuntimeException) {
121118 throw (RuntimeException) ex;
122119 } else if (ex instanceof ParseException) {
125122 throw new RuntimeException(ex.toString(), ex);
126123 }
127124 } else {
128 StringBuffer err = new StringBuffer();
129 for (Iterator iter = errors.iterator(); iter.hasNext();) {
130 Exception ex = (Exception) iter.next();
125 StringBuilder err = new StringBuilder();
126 for (Exception ex : errors) {
131127 err.append("\t").append(StringUtils.getErrorMessage(ex)).append("\n");
132128 }
133129 err.setLength(err.length() - 1);
172168 }
173169
174170 public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
175 for (Iterator iter = chain.iterator(); iter.hasNext();) {
176 DependencyResolver resolver = (DependencyResolver) iter.next();
171 for (DependencyResolver resolver : chain) {
177172 ResolvedResource result = resolver.findIvyFileRef(dd, data);
178173 if (result != null) {
179174 return result;
180175 }
181176 }
182
183177 return null;
184178 }
185179
186 public Map[] listTokenValues(String[] tokens, Map criteria) {
187 Set result = new HashSet();
188 for (Iterator iter = chain.iterator(); iter.hasNext();) {
189 DependencyResolver resolver = (DependencyResolver) iter.next();
190 Map[] temp = resolver.listTokenValues(tokens, new HashMap(criteria));
180 @SuppressWarnings("unchecked")
181 @Override
182 public Map<String, String>[] listTokenValues(String[] tokens, Map<String, Object> criteria) {
183 Set<Map<String, String>> result = new HashSet<>();
184 for (DependencyResolver resolver : chain) {
185 Map<String, String>[] temp = resolver.listTokenValues(tokens,
186 new HashMap<>(criteria));
191187 result.addAll(Arrays.asList(temp));
192188 }
193189
194 return (Map[]) result.toArray(new Map[result.size()]);
195 }
196
190 return result.toArray(new Map[result.size()]);
191 }
192
193 @Override
197194 public void reportFailure() {
198 for (Iterator iter = chain.iterator(); iter.hasNext();) {
199 DependencyResolver resolver = (DependencyResolver) iter.next();
195 for (DependencyResolver resolver : chain) {
200196 resolver.reportFailure();
201197 }
202198 }
203199
200 @Override
204201 public void reportFailure(Artifact art) {
205 for (Iterator iter = chain.iterator(); iter.hasNext();) {
206 DependencyResolver resolver = (DependencyResolver) iter.next();
202 for (DependencyResolver resolver : chain) {
207203 resolver.reportFailure(art);
208204 }
209205 }
210206
211207 public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
212 List artifactsToDownload = new ArrayList(Arrays.asList(artifacts));
208 List<Artifact> artifactsToDownload = new ArrayList<>(Arrays.asList(artifacts));
213209 DownloadReport report = new DownloadReport();
214 for (Iterator iter = chain.iterator(); iter.hasNext() && !artifactsToDownload.isEmpty();) {
215 DependencyResolver resolver = (DependencyResolver) iter.next();
210 for (DependencyResolver resolver : chain) {
211 if (artifactsToDownload.isEmpty()) {
212 break;
213 }
216214 DownloadReport r = resolver.download(
217 (Artifact[]) artifactsToDownload.toArray(new Artifact[artifactsToDownload.size()]),
218 options);
219 ArtifactDownloadReport[] adr = r.getArtifactsReports();
220 for (int i = 0; i < adr.length; i++) {
221 if (adr[i].getDownloadStatus() != DownloadStatus.FAILED) {
222 artifactsToDownload.remove(adr[i].getArtifact());
223 report.addArtifactReport(adr[i]);
224 }
225 }
226 }
227 for (Iterator iter = artifactsToDownload.iterator(); iter.hasNext();) {
228 Artifact art = (Artifact) iter.next();
215 artifactsToDownload.toArray(new Artifact[artifactsToDownload.size()]), options);
216 for (ArtifactDownloadReport adr : r.getArtifactsReports()) {
217 if (adr.getDownloadStatus() != DownloadStatus.FAILED) {
218 artifactsToDownload.remove(adr.getArtifact());
219 report.addArtifactReport(adr);
220 }
221 }
222 }
223 for (Artifact art : artifactsToDownload) {
229224 ArtifactDownloadReport adr = new ArtifactDownloadReport(art);
230225 adr.setDownloadStatus(DownloadStatus.FAILED);
231226 report.addArtifactReport(adr);
233228 return report;
234229 }
235230
236 public List getResolvers() {
231 public List<DependencyResolver> getResolvers() {
237232 return chain;
238233 }
239234
240235 public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
241
242236 getFirstResolver().publish(artifact, src, overwrite);
243237 }
244238
239 @Override
245240 public void abortPublishTransaction() throws IOException {
246241 getFirstResolver().abortPublishTransaction();
247242 }
248243
244 @Override
249245 public void beginPublishTransaction(ModuleRevisionId module, boolean overwrite)
250246 throws IOException {
251247 getFirstResolver().beginPublishTransaction(module, overwrite);
252248 }
253249
250 @Override
254251 public void commitPublishTransaction() throws IOException {
255252 getFirstResolver().commitPublishTransaction();
256253 }
259256 if (chain.isEmpty()) {
260257 throw new IllegalStateException("invalid chain resolver with no sub resolver");
261258 }
262 return ((DependencyResolver) chain.get(0));
259 return chain.get(0);
263260 }
264261
265262 public boolean isReturnFirst() {
270267 this.returnFirst = returnFirst;
271268 }
272269
270 @Override
273271 public void dumpSettings() {
274272 Message.verbose("\t" + getName() + " [chain] " + chain);
275273 Message.debug("\t\treturn first: " + isReturnFirst());
276274 Message.debug("\t\tdual: " + isDual());
277 for (Iterator iter = chain.iterator(); iter.hasNext();) {
278 DependencyResolver r = (DependencyResolver) iter.next();
279 Message.debug("\t\t-> " + r.getName());
280 }
281 }
282
275 for (DependencyResolver resolver : chain) {
276 Message.debug("\t\t-> " + resolver.getName());
277 }
278 }
279
280 @Override
283281 public boolean exists(Artifact artifact) {
284 for (Iterator iter = chain.iterator(); iter.hasNext();) {
285 DependencyResolver resolver = (DependencyResolver) iter.next();
282 for (DependencyResolver resolver : chain) {
286283 if (resolver.exists(artifact)) {
287284 return true;
288285 }
290287 return false;
291288 }
292289
290 @Override
293291 public ArtifactOrigin locate(Artifact artifact) {
294 for (Iterator iter = chain.iterator(); iter.hasNext();) {
295 DependencyResolver resolver = (DependencyResolver) iter.next();
292 for (DependencyResolver resolver : chain) {
296293 ArtifactOrigin origin = resolver.locate(artifact);
297294 if (!ArtifactOrigin.isUnknown(origin)) {
298295 return origin;
299296 }
300297 }
301 return ArtifactOrigin.unkwnown(artifact);
302 }
303
298 return ArtifactOrigin.unknown(artifact);
299 }
300
301 @Override
304302 public ArtifactDownloadReport download(ArtifactOrigin artifact, DownloadOptions options) {
305 for (Iterator iter = chain.iterator(); iter.hasNext();) {
306 DependencyResolver resolver = (DependencyResolver) iter.next();
303 for (DependencyResolver resolver : chain) {
307304 ArtifactDownloadReport adr = resolver.download(artifact, options);
308305 if (adr.getDownloadStatus() != DownloadStatus.FAILED) {
309306 return adr;
344341 public boolean isDual() {
345342 return dual;
346343 }
347
348344 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4545
4646 /**
4747 * Should only be used by configurator
48 *
48 *
4949 * @param name
5050 * the new name of the resolver
5151 */
5656 * latest one (i.e. a revision uniquely identifying the revision of a module in the current
5757 * environment - If this revision is not able to identify uniquely the revision of the module
5858 * outside of the current environment, then the resolved revision must begin by ##)
59 *
60 * @throws ParseException
59 *
60 * @param dd DependencyDescriptor
61 * @param data ResolveData
62 * @return ResolvedModuleRevision
63 * @throws ParseException if something goes wrong
6164 */
6265 ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
6366 throws ParseException;
6568 /**
6669 * Finds the module descriptor for the specified <tt>DependencyDescriptor</tt>. If this resolver
6770 * can't find the module descriptor, <tt>null</tt> is returned.
68 *
71 *
6972 * @param dd
7073 * the dependency descriptor
7174 * @param data
8588 * The returned DownloadReport is never <code>null</code>, and always contain an
8689 * {@link ArtifactDownloadReport} for each requested Artifact.
8790 * </p>
88 *
91 *
8992 * @param artifacts
9093 * an array of artifacts to download. Must not be <code>null</code>.
9194 * @param options
101104 * locates and downloads a set of artifacts. This method uses an {@link ArtifactOrigin}, and as
102105 * such is only used to materialize an already located Artifact.
103106 * </p>
104 *
107 *
105108 * @param artifact
106109 * the location of the artifact to download. Must not be <code>null</code>.
107110 * @param options
113116 /**
114117 * Returns <code>true</code> if the given artifact can be located by this resolver and actually
115118 * exist.
116 *
119 *
117120 * @param artifact
118121 * the artifact which should be tested.
119122 * @return <code>true</code> if the given artifact can be located by this resolver and actually
124127 /**
125128 * Locates the given artifact and returns its location if it can be located by this resolver and
126129 * if it actually exists, or <code>null</code> in other cases.
127 *
130 *
128131 * @param artifact
129132 * the artifact which should be located
130133 * @return the artifact location, or <code>null</code> if it can't be located by this resolver
147150
148151 /**
149152 * Reports last artifact download failure as Messages
150 *
151 * @param art
153 *
154 * @param art Artifact
152155 */
153156 void reportFailure(Artifact art);
154157
158161 // are registered in ivy too.
159162
160163 /**
161 * List all the values the given token can take if other tokens are set as described in the
162 * otherTokenValues map. For instance, if token = "revision" and the map contains
163 * "organisation"->"foo" "module"->"bar" The results will be the list of revisions of the module
164 * bar from the org foo.
165 * <p>
166 * Note that listing does not take into account namespaces, and return raw information without
167 * any namespace transformation. The caller is responsible for calling namespace transformation
168 * with the Namespace returned by {@link #getNamespace()}.
169 * </p>
170 */
171 String[] listTokenValues(String token, Map otherTokenValues);
164 * List all the values the given token can take if other tokens are set as
165 * described in the otherTokenValues map. For instance, if
166 * token = "revision" and the map contains "organisation"-&gt;"foo" "module"-&gt;"bar"
167 * The results will be the list of revisions of the module bar from the org foo.
168 * <p>
169 * Note that listing does not take into account namespaces, and return raw
170 * information without any namespace transformation. The caller is
171 * responsible for calling namespace transformation with the Namespace
172 * returned by {@link #getNamespace()}.
173 * </p>
174 *
175 * @param token String
176 * @param otherTokenValues Map
177 * @return String[]
178 */
179 String[] listTokenValues(String token, Map<String, String> otherTokenValues);
172180
173181 /**
174182 * Same as {@link #listTokenValues(String, Map)} but more generic.
175 *
183 *
176184 * @param tokens
177185 * the tokens of the query
178186 * @param criteria
179187 * the token which have values
180 * @return the list of token values (Map<Strin, String>[]), must not be <code>null</code>
181 */
182 Map[] listTokenValues(String[] tokens, Map criteria);
188 * @return the list of token values, must not be <code>null</code>
189 */
190 Map<String, String>[] listTokenValues(String[] tokens, Map<String, Object> criteria);
183191
184192 OrganisationEntry[] listOrganisations();
185193
189197
190198 /**
191199 * Returns the namespace associated with this resolver.
192 *
200 *
193201 * @return the namespace associated with this resolver.
194202 */
195203 Namespace getNamespace();
201209 /**
202210 * Returns the {@link RepositoryCacheManager} used to manage the repository cache associated
203211 * with this dependency resolver.
204 *
212 *
205213 * @return the {@link RepositoryCacheManager} used to manage the repository cache associated
206214 * with this dependency resolver.
207215 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
136136 }
137137 }
138138
139 @Override
139140 public void abortPublishTransaction() throws IOException {
140141 ivyResolver.abortPublishTransaction();
141142 artifactResolver.abortPublishTransaction();
142143 }
143144
145 @Override
144146 public void beginPublishTransaction(ModuleRevisionId module, boolean overwrite)
145147 throws IOException {
146148 ivyResolver.beginPublishTransaction(module, overwrite);
147149 artifactResolver.beginPublishTransaction(module, overwrite);
148150 }
149151
152 @Override
150153 public void commitPublishTransaction() throws IOException {
151154 ivyResolver.commitPublishTransaction();
152155 artifactResolver.commitPublishTransaction();
153156 }
154157
158 @Override
155159 public void dumpSettings() {
156160 if (ivyResolver == null || artifactResolver == null) {
157161 throw new IllegalStateException(
161165 + artifactResolver.getName() + "]");
162166 }
163167
168 @Override
164169 public boolean exists(Artifact artifact) {
165170 if (artifact.isMetadata()) {
166171 return ivyResolver.exists(artifact);
169174 }
170175 }
171176
177 @Override
172178 public ArtifactOrigin locate(Artifact artifact) {
173179 if (artifact.isMetadata()) {
174180 return ivyResolver.locate(artifact);
177183 }
178184 }
179185
186 @Override
180187 public ArtifactDownloadReport download(ArtifactOrigin artifact, DownloadOptions options) {
181188 if (artifact.getArtifact().isMetadata()) {
182189 return ivyResolver.download(artifact, options);
198205 /**
199206 * Sets the module descriptor presence rule. Should be one of {@link #DESCRIPTOR_REQUIRED} or
200207 * {@link #DESCRIPTOR_OPTIONAL}.
201 *
208 *
202209 * @param descriptorRule
203210 * the descriptor rule to use with this resolver.
204211 */
205212 public void setDescriptor(String descriptorRule) {
206 if (DESCRIPTOR_REQUIRED.equals(descriptorRule)) {
207 allownomd = false;
208 } else if (DESCRIPTOR_OPTIONAL.equals(descriptorRule)) {
209 allownomd = true;
210 } else {
211 throw new IllegalArgumentException("unknown descriptor rule '" + descriptorRule
212 + "'. Allowed rules are: "
213 + Arrays.asList(new String[] {DESCRIPTOR_REQUIRED, DESCRIPTOR_OPTIONAL}));
213 switch (descriptorRule) {
214 case DESCRIPTOR_REQUIRED:
215 allownomd = false;
216 break;
217 case DESCRIPTOR_OPTIONAL:
218 allownomd = true;
219 break;
220 default:
221 throw new IllegalArgumentException("unknown descriptor rule '" + descriptorRule
222 + "'. Allowed rules are: "
223 + Arrays.asList(DESCRIPTOR_REQUIRED, DESCRIPTOR_OPTIONAL));
214224 }
215225 }
216226
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4545
4646 /**
4747 * Transactional mode.
48 *
48 *
4949 * auto: use transaction if possible, only log verbose message if not true: always use
5050 * transaction, fail if not supported false: never use transactions
5151 */
6666 * Map between actual patterns and patterns used during the transaction to put files in a
6767 * temporary directory
6868 */
69 private Map/* <String,String> */fullTransactionPatterns = new HashMap();
69 private Map<String, String> fullTransactionPatterns = new HashMap<>();
7070
7171 /**
7272 * Location where files are published during the transaction
8282 setRepository(new FileRepository());
8383 }
8484
85 @Override
8586 public String getTypeName() {
8687 return "file";
8788 }
9899 return (FileRepository) getRepository();
99100 }
100101
102 @Override
101103 protected String getDestination(String pattern, Artifact artifact, ModuleRevisionId mrid) {
102104 if (supportTransaction() && isTransactionStarted()) {
103105
104 String destPattern = (String) fullTransactionPatterns.get(pattern);
106 String destPattern = fullTransactionPatterns.get(pattern);
105107 if (destPattern == null) {
106108 throw new IllegalArgumentException(
107109 "unsupported pattern for publish destination pattern: " + pattern
117119 return transactionTempDir != null;
118120 }
119121
122 @Override
120123 public void abortPublishTransaction() throws IOException {
121124 if (supportTransaction()) {
122125 if (isTransactionStarted()) {
132135 }
133136 }
134137
138 @Override
135139 public void commitPublishTransaction() throws IOException {
136140 if (supportTransaction()) {
137141 if (!isTransactionStarted()) {
147151 try {
148152 getFileRepository().move(transactionTempDir, transactionDestDir);
149153
150 Message.info("\tpublish commited: moved " + transactionTempDir + " \n\t\tto "
154 Message.info("\tpublish committed: moved " + transactionTempDir + " \n\t\tto "
151155 + transactionDestDir);
152156 } catch (IOException ex) {
153 IOException commitEx;
157 String message;
154158 try {
155159 getFileRepository().delete(transactionTempDir);
156 commitEx = new IOException("publish transaction commit error for "
157 + transactionDestDir + ": rolled back");
160 message = "publish transaction commit error for "
161 + transactionDestDir + ": rolled back";
158162 } catch (IOException deleteEx) {
159 commitEx = new IOException("publish transaction commit error for "
160 + transactionDestDir + ": rollback impossible either, "
161 + "please remove " + transactionTempDir + " manually");
162 }
163 commitEx.initCause(ex);
164 throw commitEx;
163 message = "publish transaction commit error for "
164 + transactionDestDir + ": rollback impossible either, "
165 + "please remove " + transactionTempDir + " manually";
166 }
167 throw new IOException(message, ex);
165168 } finally {
166169 closeTransaction();
167170 }
168171 }
169172 }
170173
174 @Override
171175 public void beginPublishTransaction(ModuleRevisionId module, boolean overwrite)
172176 throws IOException {
173177 if (supportTransaction()) {
193197 }
194198 }
195199
196 protected Collection filterNames(Collection values) {
200 @Override
201 protected Collection<String> filterNames(Collection<String> values) {
197202 if (supportTransaction()) {
198203 values = super.filterNames(values);
199 for (Iterator iterator = values.iterator(); iterator.hasNext();) {
200 String v = (String) iterator.next();
201 if (v.endsWith(TRANSACTION_DESTINATION_SUFFIX)) {
204 Iterator<String> iterator = values.iterator();
205 while (iterator.hasNext()) {
206 if (iterator.next().endsWith(TRANSACTION_DESTINATION_SUFFIX)) {
202207 iterator.remove();
203208 }
204209 }
213218 return false;
214219 }
215220 checkSupportTransaction();
216 return supportTransaction.booleanValue();
221 return supportTransaction;
217222 }
218223
219224 private void closeTransaction() {
224229 private void checkSupportTransaction() {
225230 if (supportTransaction == null) {
226231 supportTransaction = Boolean.FALSE;
227 List ivyPatterns = getIvyPatterns();
228 List artifactPatterns = getArtifactPatterns();
232 List<String> ivyPatterns = getIvyPatterns();
233 List<String> artifactPatterns = getArtifactPatterns();
229234
230235 if (ivyPatterns.size() > 0) {
231 String pattern = (String) ivyPatterns.get(0);
236 String pattern = ivyPatterns.get(0);
232237 Matcher m = TRANSACTION_PATTERN.matcher(pattern);
233238 if (!m.matches()) {
234239 unsupportedTransaction("ivy pattern does not use revision as a directory");
240245 }
241246 }
242247 if (artifactPatterns.size() > 0) {
243 String pattern = (String) artifactPatterns.get(0);
248 String pattern = artifactPatterns.get(0);
244249 Matcher m = TRANSACTION_PATTERN.matcher(pattern);
245250 if (!m.matches()) {
246251 unsupportedTransaction("artifact pattern does not use revision as a directory");
298303 this.transactional = transactional;
299304 }
300305
306 @Override
301307 public void addConfiguredIvy(IvyPattern p) {
302308 File file = Checks.checkAbsolute(p.getPattern(), "ivy pattern");
303309 p.setPattern(file.getAbsolutePath());
304310 super.addConfiguredIvy(p);
305311 }
306312
313 @Override
307314 public void addIvyPattern(String pattern) {
308315 File file = Checks.checkAbsolute(pattern, "ivy pattern");
309316 super.addIvyPattern(file.getAbsolutePath());
310317 }
311318
319 @Override
312320 public void addConfiguredArtifact(IvyPattern p) {
313321 File file = Checks.checkAbsolute(p.getPattern(), "artifact pattern");
314322 p.setPattern(file.getAbsolutePath());
315323 super.addConfiguredArtifact(p);
316324 }
317325
326 @Override
318327 public void addArtifactPattern(String pattern) {
319328 File file = Checks.checkAbsolute(pattern, "artifact pattern");
320329 super.addArtifactPattern(file.getAbsolutePath());
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1515 *
1616 */
1717 package org.apache.ivy.plugins.resolver;
18
19 import java.io.File;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.text.ParseException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Collections;
26 import java.util.Date;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.Map;
30
31 import javax.xml.parsers.ParserConfigurationException;
3218
3319 import org.apache.ivy.core.IvyPatternHelper;
3420 import org.apache.ivy.core.cache.ArtifactOrigin;
4733 import org.apache.ivy.plugins.repository.Repository;
4834 import org.apache.ivy.plugins.repository.Resource;
4935 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
36 import org.apache.ivy.plugins.version.MavenTimedSnapshotVersionMatcher;
5037 import org.apache.ivy.util.ContextualSAXHandler;
5138 import org.apache.ivy.util.Message;
5239 import org.apache.ivy.util.XMLHelper;
5340 import org.xml.sax.SAXException;
41
42 import javax.xml.parsers.ParserConfigurationException;
43 import java.io.File;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.text.ParseException;
47 import java.util.ArrayList;
48 import java.util.Collection;
49 import java.util.Collections;
50 import java.util.Date;
51 import java.util.List;
52 import java.util.Map;
5453
5554 /**
5655 * IBiblioResolver is a resolver which can be used to resolve dependencies found in the ibiblio
6463
6564 private static final String M2_PATTERN = "[organisation]/[module]/" + M2_PER_MODULE_PATTERN;
6665
66 @Deprecated
6767 public static final String DEFAULT_PATTERN = "[module]/[type]s/[artifact]-[revision].[ext]";
6868
69 public static final String DEFAULT_ROOT = "http://www.ibiblio.org/maven/";
69 @Deprecated
70 /**
71 * @deprecated This root URL is no longer valid. Use {@link #DEFAULT_M2_ROOT} instead
72 */
73 public static final String DEFAULT_ROOT = "https://www.ibiblio.org/maven/";
7074
7175 public static final String DEFAULT_M2_ROOT = "https://repo1.maven.org/maven2/";
7276
8690 setChangingPattern(".*-SNAPSHOT");
8791 }
8892
93 @Override
8994 public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
90 if (isM2compatible() && isUsepoms()) {
91 ModuleRevisionId mrid = dd.getDependencyRevisionId();
92 mrid = convertM2IdForResourceSearch(mrid);
93
94 ResolvedResource rres = null;
95 if (dd.getDependencyRevisionId().getRevision().endsWith("SNAPSHOT")) {
96 rres = findSnapshotDescriptor(dd, data, mrid);
97 if (rres != null) {
98 return rres;
99 }
100 }
101
102 rres = findResourceUsingPatterns(mrid, getIvyPatterns(),
95 if (!isM2compatible() || !isUsepoms()) {
96 return null;
97 }
98 ModuleRevisionId mrid = dd.getDependencyRevisionId();
99 mrid = convertM2IdForResourceSearch(mrid);
100 final String revision = dd.getDependencyRevisionId().getRevision();
101 final MavenTimedSnapshotVersionMatcher.MavenSnapshotRevision snapshotRevision = MavenTimedSnapshotVersionMatcher.computeIfSnapshot(revision);
102 if (snapshotRevision != null) {
103 final ResolvedResource rres = findSnapshotDescriptor(dd, data, mrid, snapshotRevision);
104 if (rres != null) {
105 return rres;
106 }
107 }
108 return findResourceUsingPatterns(mrid, getIvyPatterns(),
103109 DefaultArtifact.newPomArtifact(mrid, data.getDate()), getRMDParser(dd, data),
104110 data.getDate());
105 return rres;
106 } else {
107 return null;
108 }
109 }
110
111 }
112
113 @Override
111114 public ResolvedResource findArtifactRef(Artifact artifact, Date date) {
112115 ensureConfigured(getSettings());
113116 ModuleRevisionId mrid = artifact.getModuleRevisionId();
114117 if (isM2compatible()) {
115118 mrid = convertM2IdForResourceSearch(mrid);
116119 }
117 ResolvedResource rres = null;
118 if (artifact.getId().getRevision().endsWith("SNAPSHOT") && isM2compatible()) {
119 rres = findSnapshotArtifact(artifact, date, mrid);
120 final String revision = artifact.getId().getRevision();
121 final MavenTimedSnapshotVersionMatcher.MavenSnapshotRevision snapshotRevision = MavenTimedSnapshotVersionMatcher.computeIfSnapshot(revision);
122 if (snapshotRevision != null) {
123 final ResolvedResource rres = findSnapshotArtifact(artifact, date, mrid, snapshotRevision);
120124 if (rres != null) {
121125 return rres;
122126 }
123127 }
124128 return findResourceUsingPatterns(mrid, getArtifactPatterns(), artifact,
125 getDefaultRMDParser(artifact.getModuleRevisionId().getModuleId()), date);
126 }
127
128 private ResolvedResource findSnapshotArtifact(Artifact artifact, Date date,
129 ModuleRevisionId mrid) {
130 String rev = findSnapshotVersion(mrid);
131 if (rev != null) {
132 // replace the revision token in file name with the resolved revision
133 String pattern = getWholePattern().replaceFirst("\\-\\[revision\\]", "-" + rev);
134 return findResourceUsingPattern(mrid, pattern, artifact, getDefaultRMDParser(artifact
135 .getModuleRevisionId().getModuleId()), date);
136 }
137 return null;
138 }
139
140 private ResolvedResource findSnapshotDescriptor(DependencyDescriptor dd, ResolveData data,
141 ModuleRevisionId mrid) {
142 String rev = findSnapshotVersion(mrid);
143 if (rev != null) {
144 // here it would be nice to be able to store the resolved snapshot version, to avoid
145 // having to follow the same process to download artifacts
146
147 Message.verbose("[" + rev + "] " + mrid);
148
149 // replace the revision token in file name with the resolved revision
150 String pattern = getWholePattern().replaceFirst("\\-\\[revision\\]", "-" + rev);
151 return findResourceUsingPattern(mrid, pattern,
129 getDefaultRMDParser(artifact.getModuleRevisionId().getModuleId()), date);
130 }
131
132 private ResolvedResource findSnapshotArtifact(final Artifact artifact, final Date date,
133 final ModuleRevisionId mrid, final MavenTimedSnapshotVersionMatcher.MavenSnapshotRevision snapshotRevision) {
134 if (!isM2compatible()) {
135 return null;
136 }
137 final String snapshotArtifactPattern;
138 if (snapshotRevision.isTimestampedSnapshot()) {
139 Message.debug(mrid + " has been identified as a (Maven) timestamped snapshot revision");
140 // this is a Maven timestamped snapshot revision. Something like 1.0.0-<timestampedRev>
141 // We now get the base revision from it, which is "1.0.0" and append the "-SNAPSHOT" to it.
142 final String inferredSnapshotRevision = snapshotRevision.getBaseRevision() + "-SNAPSHOT";
143 // we replace the "/[revision]" in the descriptor pattern with the "inferred" snapshot
144 // revision which is like "1.0.0-SNAPSHOT". Ultimately, this will translate to
145 // something like
146 // org/module/1.0.0-SNAPSHOT/artifact-1.0.0-<timestampedRev>(-[classifier]).ext
147 snapshotArtifactPattern = getWholePattern().replaceFirst("/\\[revision\\]", "/" + inferredSnapshotRevision);
148 } else {
149 // it's not a timestamped revision, but a regular snapshot. Try and find any potential
150 // timestamped revisions of this regular snapshot, by looking into the Maven metadata
151 final String timestampedRev = findTimestampedSnapshotVersion(mrid);
152 if (timestampedRev == null) {
153 // no timestamped snapshots found and instead this is just a regular snapshot
154 // version. So let's just fallback to our logic of finding resources using
155 // configured artifact pattern(s)
156 return null;
157 }
158 Message.verbose(mrid + " has been identified as a snapshot revision which has a timestamped snapshot revision " + timestampedRev);
159 // we have found a timestamped revision for a snapshot. So we replace the "-[revision]"
160 // in the artifact file name to use the timestamped revision.
161 // Ultimately, this will translate to something like
162 // org/module/1.0.0-SNAPSHOT/artifact-1.0.0-<timestampedRev>(-[classifier]).ext
163 snapshotArtifactPattern = getWholePattern().replaceFirst("\\-\\[revision\\]", "-" + timestampedRev);
164 }
165 return findResourceUsingPattern(mrid, snapshotArtifactPattern, artifact, getDefaultRMDParser(artifact
166 .getModuleRevisionId().getModuleId()), date);
167 }
168
169 private ResolvedResource findSnapshotDescriptor(final DependencyDescriptor dd, final ResolveData data,
170 final ModuleRevisionId mrid,
171 final MavenTimedSnapshotVersionMatcher.MavenSnapshotRevision snapshotRevision) {
172 if (!isM2compatible()) {
173 return null;
174 }
175 final String snapshotDescriptorPattern;
176 if (snapshotRevision.isTimestampedSnapshot()) {
177 Message.debug(mrid + " has been identified as a (Maven) timestamped snapshot revision");
178 // this is a Maven timestamped snapshot revision. Something like 1.0.0-<timestampedRev>
179 // We now get the base revision from it, which is "1.0.0" and append the "-SNAPSHOT" to it.
180 final String inferredSnapshotRevision = snapshotRevision.getBaseRevision() + "-SNAPSHOT";
181 // we replace the "/[revision]" in the descriptor pattern with the "inferred" snapshot
182 // revision which is like "1.0.0-SNAPSHOT".
183 // Ultimately, this will translate to something like
184 // org/module/1.0.0-SNAPSHOT/artifact-1.0.0-<timestampedRev>(-[classifier]).ext
185 snapshotDescriptorPattern = getWholePattern().replaceFirst("/\\[revision\\]", "/" + inferredSnapshotRevision);
186 } else {
187 // it's not a timestamped revision, but a regular snapshot. Try and find any potential
188 // timestamped revisions of this regular snapshot, by looking into the Maven metadata
189 final String timestampedRev = findTimestampedSnapshotVersion(mrid);
190 if (timestampedRev == null) {
191 // no timestamped snapshots found and instead this is just a regular snapshot
192 // version. So let's just fallback to our logic of finding resources using
193 // configured Ivy pattern(s)
194 return null;
195 }
196 Message.verbose(mrid + " has been identified as a snapshot revision which has a timestamped snapshot revision " + timestampedRev);
197 // we have found a timestamped revision for a snapshot. So we replace the "-[revision]"
198 // in the artifact file name to use the timestamped revision.
199 // Ultimately, this will translate to something like
200 // org/module/1.0.0-SNAPSHOT/artifact-1.0.0-<timestampedRev>(-[classifier]).ext
201 snapshotDescriptorPattern = getWholePattern().replaceFirst("\\-\\[revision\\]", "-" + timestampedRev);
202 }
203 // find the descriptor using the snapshot descriptor pattern
204 return findResourceUsingPattern(mrid, snapshotDescriptorPattern,
152205 DefaultArtifact.newPomArtifact(mrid, data.getDate()), getRMDParser(dd, data),
153206 data.getDate());
154 }
155 return null;
156 }
157
158 private String findSnapshotVersion(ModuleRevisionId mrid) {
207 }
208
209 private String findTimestampedSnapshotVersion(final ModuleRevisionId mrid) {
159210 if (!isM2compatible()) {
160211 return null;
161212 }
162
163 if (shouldUseMavenMetadata(getWholePattern())) {
164 InputStream metadataStream = null;
165 try {
166 String metadataLocation = IvyPatternHelper.substitute(root
167 + "[organisation]/[module]/[revision]/maven-metadata.xml", mrid);
168 Resource metadata = getRepository().getResource(metadataLocation);
169 if (metadata.exists()) {
170 metadataStream = metadata.openStream();
171 final StringBuffer timestamp = new StringBuffer();
172 final StringBuffer buildNumer = new StringBuffer();
173 XMLHelper.parse(metadataStream, null, new ContextualSAXHandler() {
174 public void endElement(String uri, String localName, String qName)
175 throws SAXException {
176 if ("metadata/versioning/snapshot/timestamp".equals(getContext())) {
177 timestamp.append(getText());
178 }
179 if ("metadata/versioning/snapshot/buildNumber".equals(getContext())) {
180 buildNumer.append(getText());
181 }
182 super.endElement(uri, localName, qName);
213 if (!shouldUseMavenMetadata(getWholePattern())) {
214 return null;
215 }
216 try {
217 final String metadataLocation = IvyPatternHelper.substitute(root
218 + "[organisation]/[module]/[revision]/maven-metadata.xml", mrid);
219 final Resource metadata = getRepository().getResource(metadataLocation);
220 if (!metadata.exists()) {
221 Message.verbose("\tmaven-metadata not available for: " + mrid);
222 return null;
223 }
224 try (final InputStream metadataStream = metadata.openStream()) {
225 final StringBuilder timestamp = new StringBuilder();
226 final StringBuilder buildNumber = new StringBuilder();
227 XMLHelper.parse(metadataStream, null, new ContextualSAXHandler() {
228 @Override
229 public void endElement(String uri, String localName, String qName)
230 throws SAXException {
231 if ("metadata/versioning/snapshot/timestamp".equals(getContext())) {
232 timestamp.append(getText());
183233 }
184 }, null);
185 if (timestamp.length() > 0) {
186 // we have found a timestamp, so this is a snapshot unique version
187 String rev = mrid.getRevision();
188 rev = rev.substring(0, rev.length() - "SNAPSHOT".length());
189 rev = rev + timestamp.toString() + "-" + buildNumer.toString();
190
191 return rev;
234 if ("metadata/versioning/snapshot/buildNumber".equals(getContext())) {
235 buildNumber.append(getText());
236 }
237 super.endElement(uri, localName, qName);
192238 }
193 } else {
194 Message.verbose("\tmaven-metadata not available: " + metadata);
239 }, null);
240 if (timestamp.length() > 0) {
241 // we have found a timestamp, so this is a snapshot unique version
242 String rev = mrid.getRevision();
243 rev = rev.substring(0, rev.length() - "SNAPSHOT".length());
244 rev += timestamp.toString() + "-" + buildNumber.toString();
245
246 return rev;
195247 }
196 } catch (IOException e) {
197 Message.verbose("impossible to access maven metadata file, ignored", e);
198 } catch (SAXException e) {
199 Message.verbose("impossible to parse maven metadata file, ignored", e);
200 } catch (ParserConfigurationException e) {
201 Message.verbose("impossible to parse maven metadata file, ignored", e);
202 } finally {
203 if (metadataStream != null) {
204 try {
205 metadataStream.close();
206 } catch (IOException e) {
207 // ignored
208 }
209 }
210 }
248 }
249 } catch (IOException | SAXException | ParserConfigurationException e) {
250 Message.debug("impossible to access maven metadata file, ignored", e);
211251 }
212252 return null;
213253 }
214254
255 @Override
215256 public void setM2compatible(boolean m2compatible) {
216257 super.setM2compatible(m2compatible);
217258 if (m2compatible) {
249290 }
250291 }
251292
293 @Override
252294 protected String getModuleDescriptorExtension() {
253295 return "pom";
254296 }
277319 /**
278320 * Sets the root of the maven like repository. The maven like repository is necessarily an http
279321 * repository.
280 *
281 * @param root
282 * the root of the maven like repository
283 * @throws IllegalArgumentException
284 * if root does not start with "http://"
322 *
323 * @param root the root of the maven like repository
324 * @throws IllegalArgumentException if root does not start with "http://"
285325 */
286326 public void setRoot(String root) {
287327 if (root == null) {
300340 if (isM2compatible() && isUsepoms()) {
301341 setIvyPatterns(Collections.singletonList(getWholePattern()));
302342 } else {
303 setIvyPatterns(Collections.EMPTY_LIST);
343 setIvyPatterns(Collections.<String>emptyList());
304344 }
305345 setArtifactPatterns(Collections.singletonList(getWholePattern()));
306346 }
310350 }
311351
312352 // we do not allow to list organisations on ibiblio, nor modules in ibiblio 1
313 public String[] listTokenValues(String token, Map otherTokenValues) {
353 @Override
354 public String[] listTokenValues(String token, Map<String, String> otherTokenValues) {
314355 if (IvyPatternHelper.ORGANISATION_KEY.equals(token)) {
315356 return new String[0];
316357 }
321362 return super.listTokenValues(token, otherTokenValues);
322363 }
323364
365 @Override
324366 protected String[] listTokenValues(String pattern, String token) {
325367 if (IvyPatternHelper.ORGANISATION_KEY.equals(token)) {
326368 return new String[0];
339381 * has been done in the given pattern
340382 */
341383 String partiallyResolvedM2PerModulePattern = IvyPatternHelper.substituteTokens(
342 M2_PER_MODULE_PATTERN, Collections.singletonMap(IvyPatternHelper.EXT_KEY, "pom"));
384 M2_PER_MODULE_PATTERN, Collections.singletonMap(IvyPatternHelper.EXT_KEY, "pom"));
343385 if (pattern.endsWith(partiallyResolvedM2PerModulePattern)) {
344386 /*
345387 * the given pattern already contain resolved org and module, we just have to
347389 * maven metadata file location
348390 */
349391 String metadataLocation = pattern.substring(0,
350 pattern.lastIndexOf(partiallyResolvedM2PerModulePattern))
392 pattern.lastIndexOf(partiallyResolvedM2PerModulePattern))
351393 + "maven-metadata.xml";
352 List revs = listRevisionsWithMavenMetadata(getRepository(), metadataLocation);
394 List<String> revs = listRevisionsWithMavenMetadata(getRepository(),
395 metadataLocation);
353396 if (revs != null) {
354 return (String[]) revs.toArray(new String[revs.size()]);
397 return revs.toArray(new String[revs.size()]);
355398 }
356399 } else {
357400 /*
367410 return super.listTokenValues(pattern, token);
368411 }
369412
413 @Override
370414 public OrganisationEntry[] listOrganisations() {
371415 return new OrganisationEntry[0];
372416 }
373417
418 @Override
374419 public ModuleEntry[] listModules(OrganisationEntry org) {
375420 if (isM2compatible()) {
376421 ensureConfigured(getSettings());
379424 return new ModuleEntry[0];
380425 }
381426
427 @Override
382428 public RevisionEntry[] listRevisions(ModuleEntry mod) {
383429 ensureConfigured(getSettings());
384430 return super.listRevisions(mod);
385431 }
386432
433 @Override
387434 protected ResolvedResource[] listResources(Repository repository, ModuleRevisionId mrid,
388 String pattern, Artifact artifact) {
435 String pattern, Artifact artifact) {
389436 if (shouldUseMavenMetadata(pattern)) {
390 List revs = listRevisionsWithMavenMetadata(repository, mrid.getModuleId()
437 List<String> revs = listRevisionsWithMavenMetadata(repository, mrid.getModuleId()
391438 .getAttributes());
392439 if (revs != null) {
393440 Message.debug("\tfound revs: " + revs);
394 List rres = new ArrayList();
395 for (Iterator iter = revs.iterator(); iter.hasNext();) {
396 String rev = (String) iter.next();
441 List<ResolvedResource> rres = new ArrayList<>();
442 for (String rev : revs) {
397443 ModuleRevisionId historicalMrid = ModuleRevisionId.newInstance(mrid, rev);
398444
399445 String patternForRev = pattern;
400446 if (rev.endsWith("SNAPSHOT")) {
401 String snapshotVersion = findSnapshotVersion(historicalMrid);
447 String snapshotVersion = findTimestampedSnapshotVersion(historicalMrid);
402448 if (snapshotVersion != null) {
403449 patternForRev = pattern.replaceFirst("\\-\\[revision\\]", "-"
404450 + snapshotVersion);
405451 }
406452 }
407453 String resolvedPattern = IvyPatternHelper.substitute(patternForRev,
408 historicalMrid, artifact);
454 historicalMrid, artifact);
409455 try {
410456 Resource res = repository.getResource(resolvedPattern);
411457 if (res != null) {
416462 }
417463 } catch (IOException e) {
418464 Message.warn(
419 "impossible to get resource from name listed by maven-metadata.xml:"
420 + rres, e);
465 "impossible to get resource from name listed by maven-metadata.xml:"
466 + rres, e);
421467 }
422468 }
423 return (ResolvedResource[]) rres.toArray(new ResolvedResource[rres.size()]);
469 return rres.toArray(new ResolvedResource[rres.size()]);
424470 } else {
425471 // maven metadata not available or something went wrong,
426472 // use default listing capability
431477 }
432478 }
433479
434 private List listRevisionsWithMavenMetadata(Repository repository, Map tokenValues) {
480 private List<String> listRevisionsWithMavenMetadata(Repository repository,
481 Map<String, String> tokenValues) {
435482 String metadataLocation = IvyPatternHelper.substituteTokens(root
436483 + "[organisation]/[module]/maven-metadata.xml", tokenValues);
437484 return listRevisionsWithMavenMetadata(repository, metadataLocation);
438485 }
439486
440 private List listRevisionsWithMavenMetadata(Repository repository, String metadataLocation) {
441 List revs = null;
487 private List<String> listRevisionsWithMavenMetadata(Repository repository,
488 String metadataLocation) {
489 List<String> revs = null;
442490 InputStream metadataStream = null;
443491 try {
444492 Resource metadata = repository.getResource(metadataLocation);
445493 if (metadata.exists()) {
446494 Message.verbose("\tlisting revisions from maven-metadata: " + metadata);
447 final List metadataRevs = new ArrayList();
495 final List<String> metadataRevs = new ArrayList<>();
448496 metadataStream = metadata.openStream();
449497 XMLHelper.parse(metadataStream, null, new ContextualSAXHandler() {
498 @Override
450499 public void endElement(String uri, String localName, String qName)
451500 throws SAXException {
452501 if ("metadata/versioning/versions/version".equals(getContext())) {
461510 }
462511 } catch (IOException e) {
463512 Message.verbose("impossible to access maven metadata file, ignored", e);
464 } catch (SAXException e) {
465 Message.verbose("impossible to parse maven metadata file, ignored", e);
466 } catch (ParserConfigurationException e) {
513 } catch (SAXException | ParserConfigurationException e) {
467514 Message.verbose("impossible to parse maven metadata file, ignored", e);
468515 } finally {
469516 if (metadataStream != null) {
477524 return revs;
478525 }
479526
480 protected void findTokenValues(Collection names, List patterns, Map tokenValues, String token) {
527 @Override
528 protected void findTokenValues(Collection<String> names, List<String> patterns,
529 Map<String, String> tokenValues, String token) {
481530 if (IvyPatternHelper.REVISION_KEY.equals(token)) {
482531 if (shouldUseMavenMetadata(getWholePattern())) {
483 List revs = listRevisionsWithMavenMetadata(getRepository(), tokenValues);
532 List<String> revs = listRevisionsWithMavenMetadata(getRepository(), tokenValues);
484533 if (revs != null) {
485534 names.addAll(filterNames(revs));
486535 return;
494543 return isUseMavenMetadata() && isM2compatible() && pattern.endsWith(M2_PATTERN);
495544 }
496545
546 @Override
497547 public String getTypeName() {
498548 return "ibiblio";
499549 }
500550
501551 // override some methods to ensure configuration
552 @Override
502553 public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
503554 throws ParseException {
504555 ensureConfigured(data.getSettings());
505556 return super.getDependency(dd, data);
506557 }
507558
559 @Override
508560 public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
509561 ensureConfigured(getSettings());
510562 return super.download(artifacts, options);
511563 }
512564
565 @Override
513566 public boolean exists(Artifact artifact) {
514567 ensureConfigured(getSettings());
515568 return super.exists(artifact);
516569 }
517570
571 @Override
518572 public ArtifactOrigin locate(Artifact artifact) {
519573 ensureConfigured(getSettings());
520574 return super.locate(artifact);
521575 }
522576
523 public List getArtifactPatterns() {
577 @Override
578 public List<String> getArtifactPatterns() {
524579 ensureConfigured(getSettings());
525580 return super.getArtifactPatterns();
526581 }
542597 this.useMavenMetadata = useMavenMetadata;
543598 }
544599
600 @Override
545601 public void dumpSettings() {
546602 ensureConfigured(getSettings());
547603 super.dumpSettings();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 import java.util.Collections;
2626 import java.util.Date;
2727 import java.util.HashMap;
28 import java.util.Iterator;
2928 import java.util.List;
3029 import java.util.Map;
3130
4342 import org.apache.ivy.plugins.resolver.util.ResolvedResource;
4443 import org.apache.ivy.util.Message;
4544 import org.apache.ivy.util.XMLHelper;
45 import org.xml.sax.Attributes;
4646 import org.xml.sax.SAXException;
4747 import org.xml.sax.helpers.DefaultHandler;
4848
5555 public class IvyRepResolver extends URLResolver {
5656 public static final String DEFAULT_IVYPATTERN = "[organisation]/[module]/ivy-[revision].xml";
5757
58 public static final String DEFAULT_IVYROOT = "http://ivyrep.jayasoft.org/";
5958
6059 private String ivyroot = null;
6160
148147 /**
149148 * Sets the root of the maven like repository. The maven like repository is necessarily an http
150149 * repository.
151 *
150 *
152151 * @param root
153152 * the root of the maven like repository
154153 * @throws IllegalArgumentException
167166 updateWholeIvyPattern();
168167 }
169168
169 @Override
170170 public void setM2compatible(boolean m2compatible) {
171171 if (m2compatible) {
172172 throw new IllegalArgumentException(
218218 updateWholeArtPattern();
219219 }
220220
221 @Override
221222 public OrganisationEntry[] listOrganisations() {
222223 ensureIvyConfigured(getSettings());
223224 try {
224225 URL content = new URL(ivyroot + "content.xml");
225 final List ret = new ArrayList();
226 final List<OrganisationEntry> ret = new ArrayList<>();
226227 XMLHelper.parse(content, null, new DefaultHandler() {
228 @Override
227229 public void startElement(String uri, String localName, String qName,
228 org.xml.sax.Attributes attributes) throws SAXException {
230 Attributes attributes) throws SAXException {
229231 if ("organisation".equals(qName)) {
230232 String org = attributes.getValue("name");
231233 if (org != null) {
234236 }
235237 }
236238 });
237 return (OrganisationEntry[]) ret.toArray(new OrganisationEntry[ret.size()]);
239 return ret.toArray(new OrganisationEntry[ret.size()]);
238240 } catch (MalformedURLException e) {
239241 // ???
240242 } catch (Exception e) {
245247
246248 // overwrite parent to use only ivy patterns (and not artifact ones, cause ibiblio is too slow
247249 // to answer)
250 @Override
248251 public ModuleEntry[] listModules(OrganisationEntry org) {
249252 ensureIvyConfigured(getSettings());
250 Map tokenValues = new HashMap();
253 Map<String, String> tokenValues = new HashMap<>();
251254 tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org.getOrganisation());
252 Collection names = findIvyNames(tokenValues, IvyPatternHelper.MODULE_KEY);
253 ModuleEntry[] ret = new ModuleEntry[names.size()];
254 int i = 0;
255 for (Iterator iter = names.iterator(); iter.hasNext(); i++) {
256 String name = (String) iter.next();
257 ret[i] = new ModuleEntry(org, name);
258 }
259 return ret;
260 }
261
255 Collection<String> names = findIvyNames(tokenValues, IvyPatternHelper.MODULE_KEY);
256 List<ModuleEntry> ret = new ArrayList<>(names.size());
257 for (String name : names) {
258 ret.add(new ModuleEntry(org, name));
259 }
260 return ret.toArray(new ModuleEntry[names.size()]);
261 }
262
263 @Override
262264 public RevisionEntry[] listRevisions(ModuleEntry mod) {
263265 ensureIvyConfigured(getSettings());
264266 ensureArtifactConfigured(getSettings());
265267 return super.listRevisions(mod);
266268 }
267269
270 @Override
268271 public String getTypeName() {
269272 return "ivyrep";
270273 }
271274
272275 // override some methods to ensure configuration
276 @Override
273277 public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
274278 throws ParseException {
275279 ensureIvyConfigured(data.getSettings());
276280 return super.getDependency(dd, data);
277281 }
278282
283 @Override
279284 public ResolvedResource findArtifactRef(Artifact artifact, Date date) {
280285 ensureArtifactConfigured(getSettings());
281286 return super.findArtifactRef(artifact, date);
282287 }
283288
289 @Override
284290 public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
285291 ensureArtifactConfigured(getSettings());
286292 return super.download(artifacts, options);
287293 }
288294
295 @Override
289296 public boolean exists(Artifact artifact) {
290297 ensureArtifactConfigured(getSettings());
291298 return super.exists(artifact);
292299 }
293300
301 @Override
294302 public ArtifactOrigin locate(Artifact artifact) {
295303 ensureArtifactConfigured(getSettings());
296304 return super.locate(artifact);
297305 }
298306
299 public List getIvyPatterns() {
307 @Override
308 public List<String> getIvyPatterns() {
300309 ensureIvyConfigured(getSettings());
301310 return super.getIvyPatterns();
302311 }
303312
304 public List getArtifactPatterns() {
313 @Override
314 public List<String> getArtifactPatterns() {
305315 ensureArtifactConfigured(getSettings());
306316 return super.getArtifactPatterns();
307317 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3636 private URL url;
3737
3838 public JarResolver() {
39 setRepository(new JarRepository());
39 setRepository(new JarRepository(new LazyTimeoutConstraint(this)));
4040 }
4141
42 @Override
4243 public String getTypeName() {
4344 return "jar";
4445 }
7172 getJarRepository().setJarFile(jar);
7273 }
7374
75 @Override
7476 public void setSettings(ResolverSettings settings) {
7577 super.setSettings(settings);
78 if (url == null) {
79 return;
80 }
7681 // let's resolve the url
77 if (url != null) {
78 ArtifactDownloadReport report;
79 EventManager eventManager = getEventManager();
80 try {
81 if (eventManager != null) {
82 getRepository().addTransferListener(eventManager);
83 }
84 Resource jarResource = new URLResource(url);
85 CacheResourceOptions options = new CacheResourceOptions();
86 report = getRepositoryCacheManager().downloadRepositoryResource(jarResource,
87 "jarrepository", "jar", "jar", options, new URLRepository());
88 } finally {
89 if (eventManager != null) {
90 getRepository().removeTransferListener(eventManager);
91 }
82 ArtifactDownloadReport report;
83 EventManager eventManager = getEventManager();
84 try {
85 if (eventManager != null) {
86 getRepository().addTransferListener(eventManager);
9287 }
93 if (report.getDownloadStatus() == DownloadStatus.FAILED) {
94 throw new RuntimeException("The jar file " + url.toExternalForm()
95 + " could not be downloaded (" + report.getDownloadDetails() + ")");
88 Resource jarResource = new URLResource(url, this.getTimeoutConstraint());
89 CacheResourceOptions options = new CacheResourceOptions();
90 report = getRepositoryCacheManager().downloadRepositoryResource(jarResource,
91 "jarrepository", "jar", "jar", options, new URLRepository());
92 } finally {
93 if (eventManager != null) {
94 getRepository().removeTransferListener(eventManager);
9695 }
97 setJarFile(report.getLocalFile());
9896 }
97 if (report.getDownloadStatus() == DownloadStatus.FAILED) {
98 throw new RuntimeException("The jar file " + url.toExternalForm()
99 + " could not be downloaded (" + report.getDownloadDetails() + ")");
100 }
101 setJarFile(report.getLocalFile());
99102 }
100103 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 package org.apache.ivy.plugins.resolver;
19
20 import org.apache.ivy.core.settings.TimeoutConstraint;
21
22 /**
23 * A {@link TimeoutConstraint} which determines the timeouts by invoking the {@link AbstractResolver
24 * underlying resolver}'s {@link AbstractResolver#getTimeoutConstraint()}, whenever the timeouts are
25 * requested for. This class can be used when the {@link TimeoutConstraint} is to be created but the
26 * underlying resolver, which decides the timeouts, hasn't yet been fully initialized
27 */
28 final class LazyTimeoutConstraint implements TimeoutConstraint {
29
30 private final AbstractResolver resolver;
31
32 public LazyTimeoutConstraint(final AbstractResolver resolver) {
33 this.resolver = resolver;
34 }
35
36 @Override
37 public int getConnectionTimeout() {
38 final TimeoutConstraint resolverTimeoutConstraint = resolver.getTimeoutConstraint();
39 return resolverTimeoutConstraint == null ? -1 : resolverTimeoutConstraint.getConnectionTimeout();
40 }
41
42 @Override
43 public int getReadTimeout() {
44 final TimeoutConstraint resolverTimeoutConstraint = resolver.getTimeoutConstraint();
45 return resolverTimeoutConstraint == null ? -1 : resolverTimeoutConstraint.getReadTimeout();
46 }
47 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import java.net.MalformedURLException;
2525 import java.net.URL;
2626 import java.util.ArrayList;
27 import java.util.Iterator;
2827 import java.util.List;
2928
3029 import org.apache.ivy.core.cache.CacheResourceOptions;
3130 import org.apache.ivy.core.report.ArtifactDownloadReport;
3231 import org.apache.ivy.osgi.repo.RelativeURLRepository;
32 import org.apache.ivy.plugins.repository.Repository;
3333 import org.apache.ivy.plugins.repository.url.ChainedRepository;
3434 import org.apache.ivy.plugins.repository.url.URLRepository;
3535 import org.apache.ivy.plugins.repository.url.URLResource;
4949
5050 private void setupMirrors() {
5151 File mirrorListFile = downloadMirrorList();
52 List mirrorBaseUrls;
52 List<String> mirrorBaseUrls;
5353 try {
5454 mirrorBaseUrls = readMirrorList(mirrorListFile);
5555 } catch (IOException e) {
5656 throw new IllegalStateException("The mirror list could not be read from "
5757 + mirrorListUrl + " (" + e.getMessage() + ")");
5858 }
59 List/* <Repository> */repositories = new ArrayList();
60 Iterator it = mirrorBaseUrls.iterator();
61 while (it.hasNext()) {
62 String baseUrl = (String) it.next();
59 List<Repository> repositories = new ArrayList<>();
60 for (String baseUrl : mirrorBaseUrls) {
6361 URL url = null;
6462 try {
6563 url = new URL(baseUrl);
6866 + ", an incorrect url has been found and will then not be used: " + baseUrl);
6967 }
7068 if (url != null) {
71 RelativeURLRepository repo = new RelativeURLRepository(url);
69 final RelativeURLRepository repo = new RelativeURLRepository(url, this.getTimeoutConstraint());
7270 repositories.add(repo);
7371 }
7472 }
7674 }
7775
7876 private File downloadMirrorList() {
79 URLRepository urlRepository = new URLRepository();
77 final URLRepository urlRepository = new URLRepository(this.getTimeoutConstraint());
8078 if (getEventManager() != null) {
8179 urlRepository.addTransferListener(getEventManager());
8280 }
83 URLResource mirrorResource = new URLResource(mirrorListUrl);
81 final URLResource mirrorResource = new URLResource(mirrorListUrl, this.getTimeoutConstraint());
8482 CacheResourceOptions options = new CacheResourceOptions();
8583 ArtifactDownloadReport report = getRepositoryCacheManager().downloadRepositoryResource(
8684 mirrorResource, "mirrorlist", "text", "txt", options, urlRepository);
8785 return report.getLocalFile();
8886 }
8987
90 private List/* <String> */readMirrorList(File mirrorListFile) throws IOException {
91 BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(
92 mirrorListFile)));
93 List/* <String> */list = new ArrayList();
94 try {
88 private List<String> readMirrorList(File mirrorListFile) throws IOException {
89 List<String> list = new ArrayList<>();
90 try (BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(
91 mirrorListFile)))) {
9592 String line = in.readLine();
9693 while (line != null) {
9794 list.add(line);
9895 line = in.readLine();
9996 }
100 } finally {
101 in.close();
10297 }
10398 return list;
10499 }
105100
101 @Override
106102 public String getTypeName() {
107103 return "mirroredurl";
108104 }
109105
106 @Override
110107 public void validate() {
111108 super.validate();
112109 setupMirrors();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.ByteArrayInputStream;
2020 import java.io.File;
2121 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URL;
2224 import java.text.ParseException;
2325 import java.util.ArrayList;
2426 import java.util.Arrays;
2527 import java.util.Collection;
2628 import java.util.Date;
27 import java.util.Iterator;
2829 import java.util.List;
2930 import java.util.Map;
3031
5051 import org.apache.ivy.util.FileUtil;
5152 import org.apache.ivy.util.Message;
5253
54 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
55
5356 /**
5457 *
5558 */
7275 this.repository = repository;
7376 }
7477
78 @Override
7579 public void setName(String name) {
7680 super.setName(name);
7781 if (repository instanceof AbstractRepository) {
8387 this.signerName = signerName;
8488 }
8589
90 @Override
8691 protected ResolvedResource findResourceUsingPattern(ModuleRevisionId mrid, String pattern,
8792 Artifact artifact, ResourceMDParser rmdparser, Date date) {
8893 String name = getName();
96101 boolean reachable = res.exists();
97102 if (reachable) {
98103 String revision;
99 if (pattern.indexOf(IvyPatternHelper.REVISION_KEY) == -1) {
104 if (pattern.contains(IvyPatternHelper.REVISION_KEY)) {
105 revision = mrid.getRevision();
106 } else {
100107 if ("ivy".equals(artifact.getType()) || "pom".equals(artifact.getType())) {
101108 // we can't determine the revision from the pattern, get it
102 // from the moduledescriptor itself
109 // from the module descriptor itself
103110 File temp = File.createTempFile("ivy", artifact.getExt());
104111 temp.deleteOnExit();
105112 repository.get(res.getName(), temp);
108115 ModuleDescriptor md = parser.parseDescriptor(getParserSettings(), temp
109116 .toURI().toURL(), res, false);
110117 revision = md.getRevision();
111 if ((revision == null) || (revision.length() == 0)) {
118 if (isNullOrEmpty(revision)) {
112119 revision = "working@" + name;
113120 }
114121 } else {
115122 revision = "working@" + name;
116123 }
117 } else {
118 revision = mrid.getRevision();
119124 }
120125 return new ResolvedResource(res, revision);
121126 } else if (versionMatcher.isDynamic(mrid)) {
128133 } else {
129134 return findDynamicResourceUsingPattern(rmdparser, mrid, pattern, artifact, date);
130135 }
131 } catch (IOException ex) {
132 throw new RuntimeException(name + ": unable to get resource for " + mrid + ": res="
133 + IvyPatternHelper.substitute(pattern, mrid, artifact) + ": " + ex, ex);
134 } catch (ParseException ex) {
136 } catch (IOException | ParseException ex) {
135137 throw new RuntimeException(name + ": unable to get resource for " + mrid + ": res="
136138 + IvyPatternHelper.substitute(pattern, mrid, artifact) + ": " + ex, ex);
137139 }
159161 }
160162 }
161163
164 @Override
162165 protected Resource getResource(String source) throws IOException {
163166 return repository.getResource(source);
164167 }
166169 /**
167170 * List all revisions as resolved resources for the given artifact in the given repository using
168171 * the given pattern, and using the given mrid except its revision.
169 *
172 *
170173 * @param repository
171174 * the repository in which revisions should be located
172175 * @param mrid
183186 return ResolverHelper.findAll(repository, mrid, pattern, artifact);
184187 }
185188
189 @Override
186190 protected long get(Resource resource, File dest) throws IOException {
187191 Message.verbose("\t" + getName() + ": downloading " + resource.getName());
188192 Message.debug("\t\tto " + dest);
196200 public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
197201 String destPattern;
198202 if ("ivy".equals(artifact.getType()) && !getIvyPatterns().isEmpty()) {
199 destPattern = (String) getIvyPatterns().get(0);
203 destPattern = getIvyPatterns().get(0);
200204 } else if (!getArtifactPatterns().isEmpty()) {
201 destPattern = (String) getArtifactPatterns().get(0);
205 destPattern = getArtifactPatterns().get(0);
202206 } else {
203207 throw new IllegalStateException("impossible to publish " + artifact + " using " + this
204208 + ": no artifact pattern defined");
224228 throws IOException {
225229 // verify the checksum algorithms before uploading artifacts!
226230 String[] checksums = getChecksumAlgorithms();
227 for (int i = 0; i < checksums.length; i++) {
228 if (!ChecksumHelper.isKnownAlgorithm(checksums[i])) {
229 throw new IllegalArgumentException("Unknown checksum algorithm: " + checksums[i]);
231 for (String checksum : checksums) {
232 if (!ChecksumHelper.isKnownAlgorithm(checksum)) {
233 throw new IllegalArgumentException("Unknown checksum algorithm: " + checksum);
230234 }
231235 }
232236
233237 repository.put(artifact, src, dest, overwrite);
234 for (int i = 0; i < checksums.length; i++) {
235 putChecksum(artifact, src, dest, overwrite, checksums[i]);
238 for (String checksum : checksums) {
239 putChecksum(artifact, src, dest, overwrite, checksum);
236240 }
237241
238242 if (signerName != null) {
246250 try {
247251 FileUtil.copy(new ByteArrayInputStream(ChecksumHelper.computeAsString(src, algorithm)
248252 .getBytes()), csFile, null);
249 repository.put(
250 DefaultArtifact.cloneWithAnotherTypeAndExt(artifact, algorithm, artifact.getExt()
251 + "." + algorithm), csFile, dest + "." + algorithm, overwrite);
253 repository.put(DefaultArtifact.cloneWithAnotherTypeAndExt(artifact, algorithm,
254 artifact.getExt() + "." + algorithm), csFile,
255 chopQuery(dest, algorithm), overwrite);
252256 } finally {
253257 csFile.delete();
254258 }
266270
267271 try {
268272 gen.sign(src, tempFile);
269 repository.put(
270 DefaultArtifact.cloneWithAnotherTypeAndExt(artifact, gen.getExtension(),
273 repository.put(DefaultArtifact.cloneWithAnotherTypeAndExt(artifact, gen.getExtension(),
271274 artifact.getExt() + "." + gen.getExtension()), tempFile,
272 dest + "." + gen.getExtension(), overwrite);
275 chopQuery(dest, gen.getExtension()), overwrite);
273276 } finally {
274277 tempFile.delete();
275278 }
276279 }
277280
281 private String chopQuery(String dest, String algorithm) {
282 if (!dest.contains("?")) {
283 return dest + "." + algorithm;
284 }
285 try {
286 URL url = new URL(dest);
287 String query = url.getQuery();
288 if (query == null ) {
289 query = "";
290 }
291 return dest.replace("?" + query, "") + "." + algorithm;
292 } catch (MalformedURLException e) {
293 throw new IllegalArgumentException(e);
294 }
295 }
296
297 @Override
278298 public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
279299 EventManager eventManager = getEventManager();
280300 try {
289309 }
290310 }
291311
292 protected void findTokenValues(Collection names, List patterns, Map tokenValues, String token) {
293 for (Iterator iter = patterns.iterator(); iter.hasNext();) {
294 String pattern = (String) iter.next();
312 @Override
313 protected void findTokenValues(Collection<String> names, List<String> patterns,
314 Map<String, String> tokenValues, String token) {
315 for (String pattern : patterns) {
295316 String partiallyResolvedPattern = IvyPatternHelper.substituteTokens(pattern,
296317 tokenValues);
297318 String[] values = ResolverHelper.listTokenValues(repository, partiallyResolvedPattern,
298319 token);
299320 if (values != null) {
300 names.addAll(filterNames(new ArrayList(Arrays.asList(values))));
301 }
302 }
303 }
304
321 names.addAll(filterNames(new ArrayList<>(Arrays.asList(values))));
322 }
323 }
324 }
325
326 @Override
305327 protected String[] listTokenValues(String pattern, String token) {
306328 return ResolverHelper.listTokenValues(repository, pattern, token);
307329 }
308330
331 @Override
309332 protected boolean exist(String path) {
310333 try {
311334 Resource resource = repository.getResource(path);
316339 }
317340 }
318341
342 @Override
319343 public String getTypeName() {
320344 return "repository";
321345 }
322346
347 @Override
323348 public void dumpSettings() {
324349 super.dumpSettings();
325350 Message.debug("\t\trepository: " + getRepository());
326351 }
327352
353 @Override
328354 public void setSettings(ResolverSettings settings) {
329355 super.setSettings(settings);
330356 if (settings != null) {
336362 }
337363
338364 public boolean isAlwaysCheckExactRevision() {
339 return alwaysCheckExactRevision == null ? true : alwaysCheckExactRevision.booleanValue();
365 return alwaysCheckExactRevision == null || alwaysCheckExactRevision;
340366 }
341367
342368 public void setAlwaysCheckExactRevision(boolean alwaysCheckExactRevision) {
343 this.alwaysCheckExactRevision = Boolean.valueOf(alwaysCheckExactRevision);
369 this.alwaysCheckExactRevision = alwaysCheckExactRevision;
344370 }
345371
346372 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5050
5151 String getResolveMode(ModuleId moduleId);
5252
53 void filterIgnore(Collection names);
53 void filterIgnore(Collection<String> names);
5454
5555 SignatureGenerator getSignatureGenerator(String name);
5656
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727 public class SFTPResolver extends AbstractSshBasedResolver {
2828
2929 public SFTPResolver() {
30 setRepository(new SFTPRepository());
30 setRepository(new SFTPRepository(new LazyTimeoutConstraint(this)));
3131 }
3232
33 @Override
3334 public String getTypeName() {
3435 return "sftp";
3536 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 public class SshResolver extends AbstractSshBasedResolver {
2525
2626 public SshResolver() {
27 setRepository(new SshRepository());
27 setRepository(new SshRepository(new LazyTimeoutConstraint(this)));
2828 }
2929
3030 /**
3131 * A four digit string (e.g., 0644, see "man chmod", "man open") specifying the permissions of
3232 * the published files.
33 *
34 * @param permissions String
3335 */
3436 public void setPublishPermissions(String permissions) {
3537 ((SshRepository) getRepository()).setPublishPermissions(permissions);
3840 /**
3941 * sets the path separator used on the target system. Not sure if this is used or if '/' is used
4042 * on all implementation. default is to use '/'
41 *
43 *
4244 * @param sep
4345 * file separator to use on the target system
4446 */
5355 /**
5456 * set the command to get a directory listing the command has to be a shell command working on
5557 * the target system and has to produce a listing of filenames, with each filename on a new line
56 * the term %arg can be used in the command to substitue the path to be listed (e.g.
58 * the term %arg can be used in the command to substitute the path to be listed (e.g.
5759 * "ls -1 %arg | grep -v CVS" to get a listing without CVS directory) if %arg is not part of the
5860 * command, the path will be appended to the command default is: "ls -1"
61 *
62 * @param cmd String
5963 */
6064 public void setListCommand(String cmd) {
6165 ((SshRepository) getRepository()).setListCommand(cmd);
6468 /**
6569 * set the command to check for existence of a file the command has to be a shell command
6670 * working on the target system and has to create an exit status of 0 for an existent file and
67 * <> 0 for a non existing file given as argument the term %arg can be used in the command to
68 * substitue the path to be listed if %arg is not part of the command, the path will be appended
69 * to the command default is: "ls"
71 * &lt;&gt; 0 for a non existing file given as argument the term %arg can be used in the command
72 * to substitute the path to be listed if %arg is not part of the command, the path will be
73 * appended to the command default is: "ls"
74 *
75 * @param cmd String
7076 */
7177 public void setExistCommand(String cmd) {
7278 ((SshRepository) getRepository()).setExistCommand(cmd);
7581 /**
7682 * set the command to create a directory on the target system the command has to be a shell
7783 * command working on the target system and has to create a directory with the given argument
78 * the term %arg can be used in the command to substitue the path to be listed if %arg is not
84 * the term %arg can be used in the command to substitute the path to be listed if %arg is not
7985 * part of the command, the path will be appended to the command default is: "mkdir"
86 *
87 * @param cmd String
8088 */
8189 public void setCreateDirCommand(String cmd) {
8290 ((SshRepository) getRepository()).setExistCommand(cmd);
8391 }
8492
93 @Override
8594 public String getTypeName() {
8695 return "ssh";
8796 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 */
2525 public class URLResolver extends RepositoryResolver {
2626 public URLResolver() {
27 setRepository(new URLRepository());
27 setRepository(new URLRepository(new LazyTimeoutConstraint(this)));
2828 }
2929
30 @Override
3031 public String getTypeName() {
3132 return "url";
3233 }
34
3335 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030 private static final int PASSWORD_GROUP = 2;
3131
3232 public VfsResolver() {
33 setRepository(new VfsRepository());
33 setRepository(new VfsRepository(new LazyTimeoutConstraint(this)));
3434 }
3535
36 @Override
3637 public String getTypeName() {
3738 return "vfs";
3839 }
3940
41 @Override
4042 public String hidePassword(String name) {
4143 return prepareForDisplay(name);
4244 }
4345
4446 public static String prepareForDisplay(String name) {
45 StringBuffer s = new StringBuffer(name);
47 StringBuilder s = new StringBuilder(name);
4648 Matcher m = URL_PATTERN.matcher(s);
4749 if (m.matches()) {
4850 final String password = m.group(PASSWORD_GROUP);
4951 final int passwordposi = s.indexOf(password);
50 StringBuffer stars = new StringBuffer(password);
52 StringBuilder stars = new StringBuilder(password);
5153 for (int posi = 0; posi < password.length(); posi++) {
5254 stars.setCharAt(posi, '*');
5355 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.ivy.plugins.repository.vsftp.VsftpRepository;
2020
2121 /**
22 * This resolver uses SecureCRT vsft to access an sftp server. It supports listing and publishing.
22 * This resolver uses SecureCRT vsftp to access an sftp server. It supports listing and publishing.
2323 * The server host should absolutely be set using setHost, so does the username.
2424 */
2525 public class VsftpResolver extends RepositoryResolver {
2626 public VsftpResolver() {
27 setRepository(new VsftpRepository());
27 setRepository(new VsftpRepository(new LazyTimeoutConstraint(this)));
2828 }
2929
30 @Override
3031 public String getTypeName() {
3132 return "vsftp";
3233 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.plugins.resolver;
18
19 import org.apache.ivy.core.settings.IvySettings;
20
21 /**
22 * Resolver which decorate normal resolver so that the workspace resolver can
23 * hijack the resolveprocess
24 * <p>NB : it is for internal usage of Ivy only!</p>
25 */
26 public class WorkspaceChainResolver extends ChainResolver {
27
28 public WorkspaceChainResolver(IvySettings settings, DependencyResolver delegate,
29 AbstractWorkspaceResolver workspaceResolver) {
30 setName("workspace-chain-" + delegate.getName());
31 setSettings(settings);
32 setReturnFirst(true);
33 add(workspaceResolver);
34 add(delegate);
35 }
36 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232
3333 /**
3434 * Where the build file should put built artifacts (relative to the build directory). Value is:
35 * * {@value}
35 * {@value}
3636 */
3737 public static final String BUILT_ARTIFACT_PATTERN = "artifacts/[type]s/[artifact].[ext]";
3838
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020 import java.io.IOException;
2121 import java.io.InputStream;
22 import java.util.Iterator;
2322 import java.util.Map;
24 import java.util.Map.Entry;
2523
2624 import org.apache.ivy.core.IvyPatternHelper;
2725 import org.apache.ivy.core.module.descriptor.Artifact;
8078
8179 /**
8280 * Attempt to build this entry.
83 *
81 *
8482 * @param packagerResource
8583 * packager metadata resource
8684 * @param properties
8785 * a map of properties to pass to the child Ant build responsible for dependency
8886 * packaging
89 *
90 * @throws IllegalStateException
87 *
88 * @throws IOException
9189 * if this entry has already been built
9290 */
93 public synchronized void build(Resource packagerResource, Map properties) throws IOException {
91 public synchronized void build(Resource packagerResource, Map<String, String> properties) throws IOException {
9492 // Sanity check
9593 if (this.built) {
9694 throw new IllegalStateException("build in directory `" + this.dir
156154 project.setUserProperty("ivy.packager.restricted", "" + this.restricted);
157155 project.setUserProperty("ivy.packager.quiet", String.valueOf(quiet));
158156 if (properties != null) {
159 for (Iterator it = properties.entrySet().iterator(); it.hasNext();) {
160 Entry entry = (Entry) it.next();
161 project.setUserProperty((String) entry.getKey(), (String) entry.getValue());
157 for (Map.Entry<String, String> entry : properties.entrySet()) {
158 project.setUserProperty(entry.getKey(), entry.getValue());
162159 }
163160 }
164161
175172
176173 /**
177174 * Has this entry been successfully built?
175 *
176 * @return boolean
178177 */
179178 public synchronized boolean isBuilt() {
180179 return this.built;
182181
183182 /**
184183 * Get a built artifact.
185 *
184 *
185 * @param artifact ditto
186 * @return ResolvedResource
186187 * @throws IllegalStateException
187188 * if this entry's built has not (yet) completed successfully
188189 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.ArrayList;
2222 import java.util.Date;
2323 import java.util.HashMap;
24 import java.util.Iterator;
2524 import java.util.LinkedHashMap;
25 import java.util.List;
2626 import java.util.Map;
2727
2828 import org.apache.ivy.core.module.descriptor.Artifact;
3535
3636 /**
3737 * Resolver that performs a "build" operation to resolve artifacts.
38 *
38 *
3939 * <p>
4040 * The resolver is configured with a base URL, from which the "ivy.xml" and "packager.xml" files are
4141 * resolved. The latter file contains instructions describing how to build the actual artifacts.
42 * </p>
4243 */
4344 public class PackagerResolver extends URLResolver {
4445
4849
4950 private static final String PACKAGER_ARTIFACT_EXT = "xml";
5051
51 private final HashMap/* <ModuleRevisionId, PackagerCacheEntry> */packagerCache = new HashMap();
52 private final Map<ModuleRevisionId, PackagerCacheEntry> packagerCache = new HashMap<>();
5253
5354 private File buildRoot;
5455
5657
5758 private String resourceURL;
5859
59 private Map/* <String,String> */properties = new LinkedHashMap();
60 private final Map<String, String> properties = new LinkedHashMap<>();
6061
6162 private boolean validate = true;
6263
8081 if (this.preserve) {
8182 return;
8283 }
83 for (Iterator i = packagerCache.values().iterator(); i.hasNext();) {
84 PackagerCacheEntry entry = (PackagerCacheEntry) i.next();
84 for (PackagerCacheEntry entry : packagerCache.values()) {
8585 entry.cleanup();
8686 }
8787 packagerCache.clear();
9292
9393 /**
9494 * Set root directory under which builds take place.
95 *
96 * @param buildRoot File
9597 */
9698 public void setBuildRoot(File buildRoot) {
9799 this.buildRoot = buildRoot;
99101
100102 /**
101103 * Returns root directory under which builds take place.
104 *
105 * @return File
102106 */
103107 public File getBuildRoot() {
104108 return buildRoot;
106110
107111 /**
108112 * Set resource cache directory.
113 *
114 * @param resourceCache File
109115 */
110116 public void setResourceCache(File resourceCache) {
111117 this.resourceCache = resourceCache;
113119
114120 /**
115121 * Get resource cache directory.
122 *
123 * @return File
116124 */
117125 public File getResourceCache() {
118126 return resourceCache;
120128
121129 /**
122130 * Set base resource override URL pattern.
131 *
132 * @param resourceURL String
123133 */
124134 public void setResourceURL(String resourceURL) {
125135 this.resourceURL = resourceURL;
127137
128138 /**
129139 * Set pattern for locating "packager.xml" files.
140 *
141 * @param pattern String
130142 */
131143 public void setPackagerPattern(String pattern) {
132 ArrayList list = new ArrayList();
144 List<String> list = new ArrayList<>();
133145 list.add(pattern);
134146 setArtifactPatterns(list);
135147 }
136148
137149 /**
138150 * Set whether to preserve build directories. Default is false.
151 *
152 * @param preserve boolean
139153 */
140154 public void setPreserveBuildDirectories(boolean preserve) {
141155 this.preserve = preserve;
143157
144158 /**
145159 * Set whether to enable restricted mode. Default is true.
160 *
161 * @param restricted boolean
146162 */
147163 public void setRestricted(boolean restricted) {
148164 this.restricted = restricted;
150166
151167 /**
152168 * Set whether to run ant with the -verbose flag. Default is false.
169 *
170 * @param verbose boolean
153171 */
154172 public void setVerbose(boolean verbose) {
155173 this.verbose = verbose;
157175
158176 /**
159177 * Set whether to run ant with the -quiet flag. Default is false.
178 *
179 * @param quiet boolean
160180 */
161181 public void setQuiet(boolean quiet) {
162182 this.quiet = quiet;
164184
165185 /**
166186 * Set whether to validate downloaded packager.xml files. Default is true.
187 *
188 * @param validate boolean
167189 */
168190 public void setValidate(boolean validate) {
169191 this.validate = validate;
184206
185207 /**
186208 * Sets a property to be passed to the child Ant build responsible for packaging the dependency.
187 *
209 *
188210 * @param propertyKey
189211 * the property to pass
190212 * @param propertyValue
217239
218240 // Check the cache
219241 ModuleRevisionId mr = artifact.getModuleRevisionId();
220 PackagerCacheEntry entry = (PackagerCacheEntry) packagerCache.get(mr);
242 PackagerCacheEntry entry = packagerCache.get(mr);
221243
222244 // Ignore invalid entries
223245 if (entry != null && !entry.isBuilt()) {
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
4545 <xslt style="packager.xsl" in="packager.xml" out="packager-output.xml">
4646 <param name="resourceURL" expression="${resourceURL}"/>
4747 <param name="restricted" expression="${ivy.packager.restricted}"/>
48 <param name="quiet" expression="${ivy.packager.quiet}"/>
48 <param name="quiet" expression="${ivy.packager.quiet}"/>
4949 </xslt>
5050 </target>
5151
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
66 "License"); you may not use this file except in compliance
77 with the License. You may obtain a copy of the License at
88
9 http://www.apache.org/licenses/LICENSE-2.0
9 https://www.apache.org/licenses/LICENSE-2.0
1010
1111 Unless required by applicable law or agreed to in writing,
1212 software distributed under the License is distributed on an
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 return pattern.startsWith("http");
3030 }
3131
32 public List listAll(URL url) throws IOException {
32 public List<URL> listAll(URL url) throws IOException {
3333 return lister.listAll(url);
3434 }
3535
36 @Override
3637 public String toString() {
3738 return "apache http lister";
3839 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4040 return pattern.startsWith("file");
4141 }
4242
43 public List listAll(URL url) throws IOException {
43 public List<URL> listAll(URL url) throws IOException {
4444 String path;
4545 try {
4646 path = new File(new URI(url.toExternalForm())).getPath();
4848 // unexpected try to get the best of it
4949 path = url.getPath();
5050 }
51 File file = basedir == null ? new File(path) : new File(basedir, path);
51 File file = (basedir == null) ? new File(path) : new File(basedir, path);
5252 if (file.exists() && file.isDirectory()) {
5353 String[] files = file.list();
54 List ret = new ArrayList(files.length);
54 List<URL> ret = new ArrayList<>(files.length);
5555 URL context = url.getPath().endsWith("/") ? url : new URL(url.toExternalForm() + "/");
56 for (int i = 0; i < files.length; i++) {
57 ret.add(new URL(context, files[i]));
56 for (String fileName : files) {
57 ret.add(new URL(context, fileName));
5858 }
5959 return ret;
6060 } else {
61 return Collections.EMPTY_LIST;
61 return Collections.emptyList();
6262 }
6363 }
6464
65 @Override
6566 public String toString() {
6667 return "file lister";
6768 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.ivy.plugins.latest.LatestStrategy;
2020
2121 public interface HasLatestStrategy {
22 public LatestStrategy getLatestStrategy();
22 LatestStrategy getLatestStrategy();
2323
24 public void setLatestStrategy(LatestStrategy latestStrategy);
24 void setLatestStrategy(LatestStrategy latestStrategy);
2525
26 public String getLatest();
26 String getLatest();
2727 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3737 return res;
3838 }
3939
40 @Override
4041 public String toString() {
4142 return res + " (" + rev + ")";
4243 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.net.URL;
2222 import java.util.ArrayList;
2323 import java.util.Arrays;
24 import java.util.Iterator;
2524 import java.util.List;
2625 import java.util.regex.Matcher;
2726 import java.util.regex.Pattern;
4847 + ": token not found in pattern");
4948 return null;
5049 }
51 if (((pattern.length() <= index + tokenString.length()) || fileSep.equals(pattern
50 if ((pattern.length() <= index + tokenString.length() || fileSep.equals(pattern
5251 .substring(index + tokenString.length(), index + tokenString.length() + 1)))
5352 && (index == 0 || fileSep.equals(pattern.substring(index - 1, index)))) {
5453 // the searched token is a whole name
5554 String root = pattern.substring(0, index);
5655 return listAll(rep, root);
57 } else {
58 int slashIndex = pattern.substring(0, index).lastIndexOf(fileSep);
59 String root = slashIndex == -1 ? "" : pattern.substring(0, slashIndex);
60
61 try {
62 Message.debug("\tusing " + rep + " to list all in " + root);
63 String[] all = listAll(rep, root);
64 if (all != null) {
65 Message.debug("\t\tfound " + all.length + " urls");
66 List<String> ret = new ArrayList<String>(all.length);
67 int endNameIndex = pattern.indexOf(fileSep, slashIndex + 1);
68 String namePattern;
69 if (endNameIndex != -1) {
70 namePattern = pattern.substring(slashIndex + 1, endNameIndex);
71 } else {
72 namePattern = pattern.substring(slashIndex + 1);
73 }
74 namePattern = namePattern.replaceAll("\\.", "\\\\.");
75 namePattern = IvyPatternHelper.substituteToken(namePattern, token, "(.+)");
76 Pattern p = Pattern.compile(namePattern);
77 for (String path : all) {
78 Matcher m = p.matcher(path);
79 if (m.matches()) {
80 String value = m.group(1);
81 ret.add(value);
82 }
83 }
84 Message.debug("\t\t" + ret.size() + " matched " + pattern);
85 return (String[]) ret.toArray(new String[ret.size()]);
86 } else {
87 return null;
88 }
89 } catch (Exception e) {
90 Message.warn("problem while listing resources in " + root + " with " + rep, e);
56 }
57
58 int slashIndex = pattern.substring(0, index).lastIndexOf(fileSep);
59 String root = (slashIndex == -1) ? "" : pattern.substring(0, slashIndex);
60 try {
61 Message.debug("\tusing " + rep + " to list all in " + root);
62 String[] all = listAll(rep, root);
63 if (all == null) {
9164 return null;
9265 }
66 Message.debug("\t\tfound " + all.length + " urls");
67 List<String> ret = new ArrayList<>(all.length);
68 int endNameIndex = pattern.indexOf(fileSep, slashIndex + 1);
69 String namePattern;
70 if (endNameIndex != -1) {
71 namePattern = pattern.substring(slashIndex + 1, endNameIndex);
72 } else {
73 namePattern = pattern.substring(slashIndex + 1);
74 }
75 namePattern = namePattern.replaceAll("\\.", "\\\\.");
76 namePattern = IvyPatternHelper.substituteToken(namePattern, token, "(.+)");
77 Pattern p = Pattern.compile(namePattern);
78 for (String path : all) {
79 Matcher m = p.matcher(path);
80 if (m.matches()) {
81 String value = m.group(1);
82 ret.add(value);
83 }
84 }
85 Message.debug("\t\t" + ret.size() + " matched " + pattern);
86 return ret.toArray(new String[ret.size()]);
87 } catch (Exception e) {
88 Message.warn("problem while listing resources in " + root + " with " + rep, e);
89 return null;
9390 }
9491 }
9592
9794 try {
9895 String fileSep = rep.getFileSeparator();
9996 Message.debug("\tusing " + rep + " to list all in " + parent);
100 List all = rep.list(parent);
101 if (all != null) {
102 Message.debug("\t\tfound " + all.size() + " resources");
103 List names = new ArrayList(all.size());
104 for (Iterator iter = all.iterator(); iter.hasNext();) {
105 String path = (String) iter.next();
106 if (path.endsWith(fileSep)) {
107 path = path.substring(0, path.length() - 1);
108 }
109 int slashIndex = path.lastIndexOf(fileSep);
110 names.add(path.substring(slashIndex + 1));
111 }
112 return (String[]) names.toArray(new String[names.size()]);
113 } else {
97 List<String> all = rep.list(parent);
98 if (all == null) {
11499 Message.debug("\t\tno resources found");
115100 return null;
116101 }
102 Message.debug("\t\tfound " + all.size() + " resources");
103 List<String> names = new ArrayList<>(all.size());
104 for (String path : all) {
105 if (path.endsWith(fileSep)) {
106 path = path.substring(0, path.length() - 1);
107 }
108 int slashIndex = path.lastIndexOf(fileSep);
109 names.add(path.substring(slashIndex + 1));
110 }
111 return names.toArray(new String[names.size()]);
117112 } catch (IOException e) {
118113 Message.verbose("problem while listing resources in " + parent + " with " + rep, e);
119114 return null;
136131 IvyPatternHelper.REVISION_KEY);
137132 if (revs != null) {
138133 Message.debug("\tfound revs: " + Arrays.asList(revs));
139 List ret = new ArrayList(revs.length);
140 for (int i = 0; i < revs.length; i++) {
134 List<ResolvedResource> ret = new ArrayList<>(revs.length);
135 for (String rev : revs) {
141136 String rres = IvyPatternHelper.substituteToken(partiallyResolvedPattern,
142 IvyPatternHelper.REVISION_KEY, revs[i]);
137 IvyPatternHelper.REVISION_KEY, rev);
143138 try {
144139 Resource res = rep.getResource(rres);
145140 if (res != null) {
146141 // we do not test if the resource actually exist here, it would cause
147142 // a lot of checks which are not always necessary depending on the usage
148143 // which is done of the returned ResolvedResource array
149 ret.add(new ResolvedResource(res, revs[i]));
144 ret.add(new ResolvedResource(res, rev));
150145 }
151146 } catch (IOException e) {
152147 Message.warn("impossible to get resource from name listed by repository: "
156151 if (revs.length != ret.size()) {
157152 Message.debug("\tfound resolved res: " + ret);
158153 }
159 return (ResolvedResource[]) ret.toArray(new ResolvedResource[ret.size()]);
160 } else if (partiallyResolvedPattern.indexOf("[" + IvyPatternHelper.REVISION_KEY + "]") == -1) {
154 return ret.toArray(new ResolvedResource[ret.size()]);
155 }
156
157 if (!partiallyResolvedPattern.contains("[" + IvyPatternHelper.REVISION_KEY + "]")) {
161158 // the partially resolved pattern is completely resolved, check the resource
162159 try {
163160 Resource res = rep.getResource(partiallyResolvedPattern);
249246 + ": token not found in pattern");
250247 return null;
251248 }
252 if (((pattern.length() <= index + tokenString.length()) || "/".equals(pattern
249 if ((pattern.length() <= index + tokenString.length() || "/".equals(pattern
253250 .substring(index + tokenString.length(), index + tokenString.length() + 1)))
254251 && (index == 0 || "/".equals(pattern.substring(index - 1, index)))) {
255252 // the searched token is a whole name
266263
267264 try {
268265 Message.debug("\tusing " + lister + " to list all in " + root);
269 List all = lister.listAll(new URL(root));
266 List<URL> all = lister.listAll(new URL(root));
270267 Message.debug("\t\tfound " + all.size() + " urls");
271 List ret = new ArrayList(all.size());
268 List<String> ret = new ArrayList<>(all.size());
272269 int endNameIndex = pattern.indexOf('/', slashIndex + 1);
273270 String namePattern;
274271 if (endNameIndex != -1) {
279276 String acceptNamePattern = ".*"
280277 + IvyPatternHelper.substituteToken(namePattern, token, "([^/]+)")
281278 + ".*";
282 Pattern p = Pattern.compile(acceptNamePattern.toString());
283 for (Iterator iter = all.iterator(); iter.hasNext();) {
284 URL url = (URL) iter.next();
279 Pattern p = Pattern.compile(acceptNamePattern);
280 for (URL url : all) {
285281 String path = standardize(url.getPath());
286282 Matcher m = p.matcher(path);
287283 if (m.matches()) {
290286 }
291287 }
292288 Message.debug("\t\t" + ret.size() + " matched " + pattern);
293 return (String[]) ret.toArray(new String[ret.size()]);
289 return ret.toArray(new String[ret.size()]);
294290 } catch (Exception e) {
295291 Message.warn("problem while listing files in " + root, e);
296292 return null;
308304 try {
309305 if (lister.accept(root.toExternalForm())) {
310306 Message.debug("\tusing " + lister + " to list all in " + root);
311 List all = lister.listAll(root);
307 List<URL> all = lister.listAll(root);
312308 Message.debug("\t\tfound " + all.size() + " urls");
313 List names = new ArrayList(all.size());
314 for (Iterator iter = all.iterator(); iter.hasNext();) {
315 URL dir = (URL) iter.next();
309 List<String> names = new ArrayList<>(all.size());
310 for (URL dir : all) {
316311 String path = dir.getPath();
317312 if (path.endsWith("/")) {
318313 path = path.substring(0, path.length() - 1);
320315 int slashIndex = path.lastIndexOf('/');
321316 names.add(path.substring(slashIndex + 1));
322317 }
323 return (String[]) names.toArray(new String[names.size()]);
318 return names.toArray(new String[names.size()]);
324319 }
325320 return null;
326321 } catch (Exception e) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 public interface ResourceMDParser {
2222 /**
2323 * Parses the module descriptor designed by the given resource.
24 *
24 *
2525 * @param resource
2626 * the resource at which the module descriptor is located
2727 * @param rev
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 /**
2525 * Indicates if this lister is able to list urls with the given pattern. In general, only
2626 * protocol is used.
27 *
28 * @param pattern
29 * @return
27 *
28 * @param pattern ditto
29 * @return boolean
3030 */
3131 boolean accept(String pattern);
3232
33 List listAll(URL url) throws IOException;
33 List<URL> listAll(URL url) throws IOException;
3434 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.io.IOException;
2323 import java.io.InputStream;
2424 import java.io.OutputStream;
25 import java.security.NoSuchAlgorithmException;
26 import java.security.NoSuchProviderException;
2725 import java.security.Security;
28 import java.security.SignatureException;
2926 import java.util.Iterator;
3027
3128 import org.apache.ivy.plugins.signer.SignatureGenerator;
4037 import org.bouncycastle.openpgp.PGPSignature;
4138 import org.bouncycastle.openpgp.PGPSignatureGenerator;
4239 import org.bouncycastle.openpgp.PGPUtil;
40 import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor;
41 import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator;
42 import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder;
43 import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder;
44 import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider;
4345
4446 public class OpenPGPSignatureGenerator implements SignatureGenerator {
4547
100102 pgpSec = readSecretKey(keyIn);
101103 }
102104
103 PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(password.toCharArray(),
104 BouncyCastleProvider.PROVIDER_NAME);
105 PGPSignatureGenerator sGen = new PGPSignatureGenerator(pgpSec.getPublicKey()
106 .getAlgorithm(), PGPUtil.SHA1, BouncyCastleProvider.PROVIDER_NAME);
107 sGen.initSign(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
105 PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(
106 new BcPGPDigestCalculatorProvider()).build(password.toCharArray());
107 PGPPrivateKey pgpPrivKey = pgpSec.extractPrivateKey(decryptor);
108 PGPSignatureGenerator sGen = new PGPSignatureGenerator(new BcPGPContentSignerBuilder(
109 pgpSec.getPublicKey().getAlgorithm(), PGPUtil.SHA1));
110 sGen.init(PGPSignature.BINARY_DOCUMENT, pgpPrivKey);
108111
109112 in = new FileInputStream(src);
110113 out = new BCPGOutputStream(new ArmoredOutputStream(new FileOutputStream(dest)));
115118 }
116119
117120 sGen.generate().encode(out);
118 } catch (SignatureException e) {
119 IOException ioexc = new IOException();
120 ioexc.initCause(e);
121 throw ioexc;
122121 } catch (PGPException e) {
123 IOException ioexc = new IOException();
124 ioexc.initCause(e);
125 throw ioexc;
126 } catch (NoSuchAlgorithmException e) {
127 IOException ioexc = new IOException();
128 ioexc.initCause(e);
129 throw ioexc;
130 } catch (NoSuchProviderException e) {
131 IOException ioexc = new IOException();
132 ioexc.initCause(e);
133 throw ioexc;
122 throw new IOException(e);
134123 } finally {
135124 if (out != null) {
136125 try {
155144
156145 private PGPSecretKey readSecretKey(InputStream in) throws IOException, PGPException {
157146 in = PGPUtil.getDecoderStream(in);
158 PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in);
147 PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(in,
148 new BcKeyFingerprintCalculator());
159149
160150 PGPSecretKey key = null;
161 for (Iterator it = pgpSec.getKeyRings(); key == null && it.hasNext();) {
162 PGPSecretKeyRing kRing = (PGPSecretKeyRing) it.next();
151 Iterator<PGPSecretKeyRing> it = pgpSec.getKeyRings();
152 while (key == null && it.hasNext()) {
153 PGPSecretKeyRing kRing = it.next();
163154
164 for (Iterator it2 = kRing.getSecretKeys(); key == null && it2.hasNext();) {
165 PGPSecretKey k = (PGPSecretKey) it2.next();
166 if ((keyId == null) && k.isSigningKey()) {
155 Iterator<PGPSecretKey> it2 = kRing.getSecretKeys();
156 while (key == null && it2.hasNext()) {
157 PGPSecretKey k = it2.next();
158 if (keyId == null && k.isSigningKey()) {
167159 key = k;
168160 }
169 if ((keyId != null)
170 && (Long.valueOf(keyId, 16).longValue() == (k.getKeyID() & MASK))) {
161 if (keyId != null && Long.valueOf(keyId, 16) == (k.getKeyID() & MASK)) {
171162 key = k;
172163 }
173164 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2828 * the only method to implement in subclasses is {@link IvyListener#progress(IvyEvent)} which should
2929 * do whatever the trigger needs to do when the event occurs. This method will only be called when
3030 * an event matching the trigger filter occurs.
31 *
31 *
3232 * @since 1.4
3333 */
3434 public abstract class AbstractTrigger implements Trigger {
35 private Filter filter;
35 private Filter<IvyEvent> filter;
3636
3737 private String event;
3838
4040
4141 private String matcher = PatternMatcher.EXACT;
4242
43 public Filter getEventFilter() {
43 public Filter<IvyEvent> getEventFilter() {
4444 if (filter == null) {
4545 filter = createFilter();
4646 }
4747 return filter;
4848 }
4949
50 private Filter createFilter() {
50 private Filter<IvyEvent> createFilter() {
5151 return new IvyEventFilter(getEvent(), getFilter(), getPatternMatcher());
5252 }
5353
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 import org.apache.ivy.core.resolve.ResolveProcessException;
3030 import org.apache.ivy.util.Message;
3131
32 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
33
3234 /**
3335 * A trigger performing logging.
3436 * <p>
3638 * </p>
3739 */
3840 public class LogTrigger extends AbstractTrigger {
39 private static final String LINE_SEPARATOR = System.getProperty("line.separator");
41 private static final String LINE_SEPARATOR = System.lineSeparator();
4042
4143 private String message = "";
4244
4547 private boolean append = true;
4648
4749 /** encoding; set to null or empty means 'default' */
48 private String encoding = "";
50 private String encoding;
4951
5052 public void progress(IvyEvent event) {
5153 log(IvyPatternHelper.substituteVariables(message, event.getAttributes()));
5355
5456 /**
5557 * Logs the given message.
56 *
58 *
5759 * @param message
5860 * the message to log
5961 */
6870 // we use the system dependent line separator to ease reading the log file
6971 message += LINE_SEPARATOR;
7072 String filename = file.getAbsolutePath();
71 if (encoding == null || encoding.length() == 0) {
73 if (isNullOrEmpty(encoding)) {
7274 out = new FileWriter(filename, append);
7375 } else {
7476 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(filename,
9193
9294 /**
9395 * Message to write.
94 *
96 *
9597 * @param msg
9698 * Sets the value for the message variable.
9799 */
101103
102104 /**
103105 * File to write to.
104 *
106 *
105107 * @param file
106108 * the file to write to, if not set, echo to standard Ivy logging
107109 */
111113
112114 /**
113115 * If true, append to existing file.
114 *
116 *
115117 * @param append
116118 * if true, append to existing file, default is false.
117119 */
122124 /**
123125 * Declare the encoding to use when outputting to a file; Use "" for the platform's default
124126 * encoding.
125 *
127 *
126128 * @param encoding
127129 * the character encoding to use.
128130 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.plugins.trigger;
1818
19 import org.apache.ivy.core.event.IvyEvent;
1920 import org.apache.ivy.core.event.IvyListener;
2021 import org.apache.ivy.util.filter.Filter;
2122
2223 public interface Trigger extends IvyListener {
23 Filter getEventFilter();
24 Filter<IvyEvent> getEventFilter();
2425 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5353 }
5454
5555 /**
56 * This method should be overriden in most cases, because it uses the default contract to return
57 * 1 when it's not possible to know which revision is greater.
56 * This method should be overridden in most cases, because it uses the default contract to
57 * return 1 when it's not possible to know which revision is greater.
58 *
59 * @param askedMrid ModuleRevisionId
60 * @param foundMrid ModuleRevisionId
61 * @param staticComparator Comparator
62 * @return int
5863 */
5964 public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
60 Comparator staticComparator) {
65 Comparator<ModuleRevisionId> staticComparator) {
6166 return 0;
6267 }
6368
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 import org.apache.ivy.util.Checks;
3030
3131 /**
32 * An implementation of {@link VersionMatcher} chaining several version matchers, and implemeting
32 * An implementation of {@link VersionMatcher} chaining several version matchers, and implementing
3333 * the {@link VersionMatcher} interface by returning results from the first matcher in the chain
3434 * accepting the version.
3535 */
3838 * The list of version matchers in the chain. This list will be queried in order, so the last
3939 * matcher will be used only if no other matcher accept the revision before.
4040 */
41 private List/* <VersionMatcher> */matchers = new LinkedList();
41 private final List<VersionMatcher> matchers = new LinkedList<>();
4242
4343 /**
4444 * Unique Constructor.
4949
5050 /**
5151 * Adds a {@link VersionMatcher} to the chain.
52 *
52 *
5353 * @param matcher
5454 * the version matcher to add. Must not be null
5555 */
6464 /**
6565 * Sets the settings this matcher will use, and set to the matcher in the chain which implements
6666 * {@link IvySettingsAware}.
67 *
67 *
6868 * @param settings
6969 * the settings to use in the whole chain. Must not be null.
7070 */
7171 public void setSettings(IvySettings settings) {
7272 super.setSettings(settings);
73 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
74 VersionMatcher matcher = (VersionMatcher) iter.next();
73 for (VersionMatcher matcher : matchers) {
7574 if (matcher instanceof IvySettingsAware) {
7675 ((IvySettingsAware) matcher).setSettings(settings);
7776 }
8281 * Returns the list of matchers in the chain.
8382 * <p>
8483 * The list is returned as an unmodifiable view on the actual list of matchers, and will thus
85 * reflect futher changes made in the chain.
86 *
84 * reflect further changes made in the chain.
85 *
8786 * @return the list of matchers in the chain. Is never null.
8887 */
89 public List getMatchers() {
88 public List<VersionMatcher> getMatchers() {
9089 return Collections.unmodifiableList(matchers);
9190 }
9291
9392 public boolean isDynamic(ModuleRevisionId askedMrid) {
9493 Checks.checkNotNull(askedMrid, "askedMrid");
95 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
96 VersionMatcher matcher = (VersionMatcher) iter.next();
94 for (VersionMatcher matcher : matchers) {
9795 if (matcher.isDynamic(askedMrid)) {
9896 return true;
9997 }
102100 }
103101
104102 public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
105 Comparator staticComparator) {
103 Comparator<ModuleRevisionId> staticComparator) {
106104 Checks.checkNotNull(askedMrid, "askedMrid");
107105 Checks.checkNotNull(foundMrid, "foundMrid");
108106 Checks.checkNotNull(staticComparator, "staticComparator");
109 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
110 VersionMatcher matcher = (VersionMatcher) iter.next();
107 for (VersionMatcher matcher : matchers) {
111108 if (matcher.isDynamic(askedMrid)) {
112109 return matcher.compare(askedMrid, foundMrid, staticComparator);
113110 }
119116 public boolean accept(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid) {
120117 Checks.checkNotNull(askedMrid, "askedMrid");
121118 Checks.checkNotNull(foundMrid, "foundMrid");
122 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
123 VersionMatcher matcher = (VersionMatcher) iter.next();
119 Iterator<VersionMatcher> iter = matchers.iterator();
120 while (iter.hasNext()) {
121 VersionMatcher matcher = iter.next();
124122 if (!iter.hasNext() || matcher.isDynamic(askedMrid)) {
125123 return matcher.accept(askedMrid, foundMrid);
126124 }
131129 public boolean needModuleDescriptor(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid) {
132130 Checks.checkNotNull(askedMrid, "askedMrid");
133131 Checks.checkNotNull(foundMrid, "foundMrid");
134 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
135 VersionMatcher matcher = (VersionMatcher) iter.next();
132 Iterator<VersionMatcher> iter = matchers.iterator();
133 while (iter.hasNext()) {
134 VersionMatcher matcher = iter.next();
136135 if (!iter.hasNext() || matcher.isDynamic(askedMrid)) {
137136 return matcher.needModuleDescriptor(askedMrid, foundMrid);
138137 }
143142 public boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor foundMD) {
144143 Checks.checkNotNull(askedMrid, "askedMrid");
145144 Checks.checkNotNull(foundMD, "foundMD");
146 for (Iterator iter = matchers.iterator(); iter.hasNext();) {
147 VersionMatcher matcher = (VersionMatcher) iter.next();
145 Iterator<VersionMatcher> iter = matchers.iterator();
146 while (iter.hasNext()) {
147 VersionMatcher matcher = iter.next();
148148 if (!iter.hasNext() || matcher.isDynamic(askedMrid)) {
149149 return matcher.accept(askedMrid, foundMD);
150150 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3838 }
3939
4040 public boolean needModuleDescriptor(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid) {
41 List statuses = StatusManager.getCurrent().getStatuses();
42 Status lowest = (Status) statuses.get(statuses.size() - 1);
41 List<Status> statuses = StatusManager.getCurrent().getStatuses();
42 Status lowest = statuses.get(statuses.size() - 1);
4343 String latestLowest = "latest." + lowest.getName();
4444 return !latestLowest.equals(askedMrid.getRevision());
4545 }
4646
4747 public boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor foundMD) {
48 String askedBranch = askedMrid.getBranch();
49 String foundBranch = foundMD.getModuleRevisionId().getBranch();
50 boolean sameBranch = (askedBranch == null) ? foundBranch == null
51 : askedBranch.equals(foundBranch);
52 if (!sameBranch) {
53 return false;
54 }
4855 String askedStatus = askedMrid.getRevision().substring("latest.".length());
4956 return StatusManager.getCurrent().getPriority(askedStatus) >= StatusManager.getCurrent()
5057 .getPriority(foundMD.getStatus());
5360 /**
5461 * If we don't need a module descriptor we can consider the dynamic revision to be greater. If
5562 * we need a module descriptor then we can't know which one is greater and return 0.
63 *
64 * @param askedMrid ModuleRevisionId
65 * @param foundMrid ModuleRevisionId
66 * @param staticComparator Comparator
67 * @return int
5668 */
5769 public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
58 Comparator staticComparator) {
70 Comparator<ModuleRevisionId> staticComparator) {
5971 return needModuleDescriptor(askedMrid, foundMrid) ? 0 : 1;
6072 }
6173 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.plugins.version;
1818
19 import java.util.ArrayList;
19 import java.util.Collections;
2020 import java.util.HashMap;
21 import java.util.LinkedList;
2122 import java.util.List;
2223 import java.util.Map;
2324 import java.util.StringTokenizer;
2930 import org.apache.ivy.plugins.matcher.PatternMatcher;
3031
3132 /**
32 *
33 *
3334 */
3435 public class Match {
3536 private String revision;
7576 public Matcher getPatternMatcher(ModuleRevisionId askedMrid) {
7677 String revision = askedMrid.getRevision();
7778
78 String[] args = split(getArgs());
79 String[] argValues = getRevisionArgs(revision);
79 List<String> args = split(getArgs());
80 List<String> argValues = getRevisionArgs(revision);
8081
81 if (args.length != argValues.length) {
82 if (args.size() != argValues.size()) {
8283 return new NoMatchMatcher();
8384 }
8485
85 Map variables = new HashMap();
86 for (int i = 0; i < args.length; i++) {
87 variables.put(args[i], argValues[i]);
86 Map<String, String> variables = new HashMap<>();
87 for (String arg : args) {
88 variables.put(arg, argValues.get(args.indexOf(arg)));
8889 }
8990
9091 String pattern = getPattern();
9495 return pMatcher.getMatcher(pattern);
9596 }
9697
97 private String[] getRevisionArgs(String revision) {
98 private List<String> getRevisionArgs(String revision) {
9899 int bracketStartIndex = revision.indexOf('(');
99100 if (bracketStartIndex == -1) {
100 return new String[0];
101 return Collections.emptyList();
101102 }
102103
103104 int bracketEndIndex = revision.indexOf(')');
104105 if (bracketEndIndex <= (bracketStartIndex + 1)) {
105 return new String[0];
106 return Collections.emptyList();
106107 }
107108
108 String args = revision.substring(bracketStartIndex + 1, bracketEndIndex);
109 return split(args);
109 return split(revision.substring(bracketStartIndex + 1, bracketEndIndex));
110110 }
111111
112 private static String[] split(String string) {
112 private static List<String> split(String string) {
113113 if (string == null) {
114 return new String[0];
114 return Collections.emptyList();
115115 }
116116
117117 StringTokenizer tokenizer = new StringTokenizer(string, ", ");
118 List tokens = new ArrayList();
118 List<String> tokens = new LinkedList<>();
119119 while (tokenizer.hasMoreTokens()) {
120120 tokens.add(tokenizer.nextToken());
121121 }
122122
123 return (String[]) tokens.toArray(new String[tokens.size()]);
123 return tokens;
124124 }
125125
126126 private static class NoMatchMatcher implements Matcher {
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 package org.apache.ivy.plugins.version;
19
20 import org.apache.ivy.core.module.id.ModuleRevisionId;
21
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
24
25 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
26
27 /**
28 * A {@link VersionMatcher} which understands {@code Maven timestamped snapshots}.
29 */
30 public class MavenTimedSnapshotVersionMatcher extends AbstractVersionMatcher {
31
32 private static final String SNAPSHOT_SUFFIX = "-SNAPSHOT";
33 // The timestamped snapshot pattern that Maven uses
34 private static final Pattern M2_TIMESTAMPED_SNAPSHOT_REV_PATTERN = Pattern.compile("^(.*)-([0-9]{8}.[0-9]{6})-([0-9]+)$");
35
36 public MavenTimedSnapshotVersionMatcher() {
37 super("maven-timed-snapshot");
38 }
39
40 @Override
41 public boolean isDynamic(final ModuleRevisionId askedMrid) {
42 if (askedMrid == null) {
43 return false;
44 }
45 // we consider only timestamped snapshots as dynamic, since unlike regular snapshots,
46 // a timestamped snapshot version of the form x.y.z-<timestamped-part> represents the real
47 // x.y.z-SNAPSHOT version
48 final Matcher snapshotPatternMatcher = M2_TIMESTAMPED_SNAPSHOT_REV_PATTERN.matcher(askedMrid.getRevision());
49 return snapshotPatternMatcher.matches();
50 }
51
52 @Override
53 public boolean accept(final ModuleRevisionId askedMrid, final ModuleRevisionId foundMrid) {
54 if (askedMrid == null || foundMrid == null) {
55 return false;
56 }
57 final MavenSnapshotRevision askedSnapshotVersion = computeIfSnapshot(askedMrid.getRevision());
58 if (askedSnapshotVersion == null) {
59 // this isn't a snapshot, so we aren't interested in it
60 return false;
61 }
62 // this version matcher only comes into picture if we have been asked to deal with a
63 // timestamped snapshot. In other words, if the asked version isn't a timestamped snapshot,
64 // then we don't accept it
65 if (!askedSnapshotVersion.isTimestampedSnapshot()) {
66 return false;
67 }
68 final MavenSnapshotRevision foundSnapshotVersion = computeIfSnapshot(foundMrid.getRevision());
69 if (foundSnapshotVersion == null) {
70 // this isn't a snapshot, so we aren't interested in it
71 return false;
72 }
73 // we compare the base revisions of both these snapshot to see if they are the same revision
74 // and if they are then we accept the "found" MRID for the "asked" MRID
75 return askedSnapshotVersion.baseRevision.equals(foundSnapshotVersion.baseRevision);
76 }
77
78 /**
79 * Parses the passed {@code revision} and returns a {@link MavenSnapshotRevision}, representing
80 * that {@code revision}, if it is either a regular snapshot (for example: 1.0.2-SNAPSHOT) or a
81 * timestamped snapshot (for example: 1.0.2-20100925.223013-19).
82 * If the passed {@code revision} isn't a snapshot revision, then this method returns null
83 *
84 * @param revision The revision to parse
85 * @return MavenSnapshotRevision
86 */
87 public static MavenSnapshotRevision computeIfSnapshot(final String revision) {
88 if (isNullOrEmpty(revision)) {
89 return null;
90 }
91 final boolean regularSnapshot = revision.endsWith(SNAPSHOT_SUFFIX);
92 final Matcher snapshotPatternMatcher = M2_TIMESTAMPED_SNAPSHOT_REV_PATTERN.matcher(revision);
93 final boolean timestampedSnaphost = snapshotPatternMatcher.matches();
94 if (!regularSnapshot && !timestampedSnaphost) {
95 // neither a regular snapshot nor a timestamped snapshot
96 return null;
97 }
98 // the revision is now identified as a snapshot (either a regular one or a timestamped one)
99 return timestampedSnaphost ? new MavenSnapshotRevision(true, revision, snapshotPatternMatcher.group(1))
100 : new MavenSnapshotRevision(false, revision, revision.substring(0, revision.indexOf(SNAPSHOT_SUFFIX)));
101 }
102
103
104 /**
105 * Represents a Maven 2 snapshot version, which is either a regular snapshot
106 * (for example: 1.0.2-SNAPSHOT) or a timestamped snapshot (for example:
107 * 1.0.2-20100925.223013-19)
108 */
109 public static final class MavenSnapshotRevision {
110
111 private final boolean timedsnapshot;
112 private final String wholeRevision;
113 private final String baseRevision;
114
115 private MavenSnapshotRevision(final boolean timedsnapshot, final String wholeRevision, final String baseRevision) {
116 if (wholeRevision == null) {
117 throw new IllegalArgumentException("Revision, of a Maven snapshot, cannot be null");
118 }
119 if (baseRevision == null) {
120 throw new IllegalArgumentException("Base revision, of a Maven snapshot revision, cannot be null");
121 }
122 this.timedsnapshot = timedsnapshot;
123 this.wholeRevision = wholeRevision;
124 this.baseRevision = baseRevision;
125 }
126
127 /**
128 * Returns true if this {@link MavenSnapshotRevision} represents a timestamped snapshot
129 * version. Else returns false.
130 *
131 * @return boolean
132 */
133 public boolean isTimestampedSnapshot() {
134 return this.timedsnapshot;
135 }
136
137 /**
138 * Returns the "base" revision that this {@link MavenSnapshotRevision} represents. For
139 * example, for the regular snapshot revision {@code 1.2.3-SNAPSHOT}, the base revision
140 * is {@code 1.2.3}. Similarly for timestamped snapshot version
141 * {@code 1.0.2-20100925.223013-19}, the base revision is {@code 1.0.2}
142 *
143 * @return String
144 */
145 public String getBaseRevision() {
146 return this.baseRevision;
147 }
148
149 /**
150 * Returns the complete/whole revision this {@link MavenSnapshotRevision} represents. For
151 * example, if this {@link MavenSnapshotRevision} represents a regular snapshot
152 * {@code 1.3.4-SNAPSHOT} revision then this method returns {@code 1.3.4-SNAPSHOT}.
153 * Similarly, if this {@link MavenSnapshotRevision} represents a timestamped snapshot
154 * {@code 1.0.2-20100925.223013-19} revision, then this method returns
155 * {@code 1.0.2-20100925.223013-19}
156 *
157 * @return String
158 */
159 public String getRevision() {
160 return this.wholeRevision;
161 }
162 }
163 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.ArrayList;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.List;
2322 import java.util.Map;
2423
2625 import org.apache.ivy.plugins.matcher.Matcher;
2726
2827 /**
29 *
28 *
3029 */
3130 public class PatternVersionMatcher extends AbstractVersionMatcher {
3231
33 private List matches = new ArrayList();
32 private final List<Match> matches = new ArrayList<>();
3433
35 private Map revisionMatches = new HashMap(); // revision -> list of Match instances
34 private final Map<String, List<Match>> revisionMatches = new HashMap<>();
35 // revision -> list of Match instances
3636
3737 private boolean init = false;
3838
4242
4343 private void init() {
4444 if (!init) {
45 for (Iterator it = matches.iterator(); it.hasNext();) {
46 Match match = (Match) it.next();
47 List revMatches = (List) revisionMatches.get(match.getRevision());
45 for (Match match : matches) {
46 List<Match> revMatches = revisionMatches.get(match.getRevision());
4847 if (revMatches == null) {
49 revMatches = new ArrayList();
48 revMatches = new ArrayList<>();
5049 revisionMatches.put(match.getRevision(), revMatches);
5150 }
5251 revMatches.add(match);
6867 revision = revision.substring(0, bracketIndex);
6968 }
7069
71 List revMatches = (List) revisionMatches.get(revision);
70 List<Match> revMatches = revisionMatches.get(revision);
7271
7372 if (revMatches != null) {
74 Iterator it = revMatches.iterator();
75 while (!accept && it.hasNext()) {
76 Match match = (Match) it.next();
73 for (Match match : revMatches) {
7774 Matcher matcher = match.getPatternMatcher(askedMrid);
7875 accept = matcher.matches(foundMrid.getRevision());
76 if (accept) {
77 break;
78 }
7979 }
8080 }
8181
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3535 }
3636
3737 public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
38 Comparator staticComparator) {
38 Comparator<ModuleRevisionId> staticComparator) {
3939 if (foundMrid.getRevision().startsWith(
4040 askedMrid.getRevision().substring(0, askedMrid.getRevision().length() - 1))) {
4141 return 1;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
4444 /**
4545 * Indicates if the given asked ModuleRevisionId should be considered as dynamic for the current
4646 * VersionMatcher or not.
47 *
47 *
4848 * @param askedMrid
4949 * the dependency module revision id as asked by a module
5050 * @return true if this revision is considered as a dynamic one, false otherwise
5151 */
52 public boolean isDynamic(ModuleRevisionId askedMrid);
52 boolean isDynamic(ModuleRevisionId askedMrid);
5353
5454 /**
5555 * Indicates if this version matcher considers that the module revision found matches the asked
5656 * one.
57 *
58 * @param askedMrid
59 * @param foundMrid
60 * @return
57 *
58 * @param askedMrid ModuleRevisionId
59 * @param foundMrid ModuleRevisionId
60 * @return boolean
6161 */
62 public boolean accept(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid);
62 boolean accept(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid);
6363
6464 /**
6565 * Indicates if this VersionMatcher needs module descriptors to determine if a module revision
6666 * matches the asked one. Note that returning true in this method may imply big performance
6767 * issues.
68 *
69 * @return
68 *
69 * @param askedMrid ModuleRevisionId
70 * @param foundMrid ModuleRevisionId
71 * @return boolean
7072 */
71 public boolean needModuleDescriptor(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid);
73 boolean needModuleDescriptor(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid);
7274
7375 /**
7476 * Indicates if this version matcher considers that the module found matches the asked one. This
7577 * method can be called even needModuleDescriptor(ModuleRevisionId askedMrid, ModuleRevisionId
7678 * foundMrid) returns false, so it is required to implement it in any case, a usual default
7779 * implementation being: return accept(askedMrid, foundMD.getResolvedModuleRevisionId());
78 *
79 * @param askedMrid
80 * @param foundMD
81 * @return
80 *
81 * @param askedMrid ModuleRevisionId
82 * @param foundMD ModuleDescriptor
83 * @return boolean
8284 */
83 public boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor foundMD);
85 boolean accept(ModuleRevisionId askedMrid, ModuleDescriptor foundMD);
8486
8587 /**
8688 * Compares a dynamic revision (askedMrid) with a static one (foundMrid) to indicate which one
8789 * should be considered the greater. If there is not enough information to know which one is the
8890 * greater, the dynamic one should be considered greater and this method should return 0. This
89 * method should never be called with a askdeMrid for which isDynamic returns false.
90 *
91 * method should never be called with a askedMrid for which isDynamic returns false.
92 *
9193 * @param askedMrid
9294 * the dynamic revision to compare
9395 * @param foundMrid
9799 * @return 0 if it's not possible to know which one is greater, greater than 0 if askedMrid
98100 * should be considered greater, lower than 0 if it can't be consider greater
99101 */
100 public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
101 Comparator staticComparator);
102 int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
103 Comparator<ModuleRevisionId> staticComparator);
102104
103105 /**
104106 * Returns the version matcher name identifying this version matcher
105 *
107 *
106108 * @return the version matcher name identifying this version matcher
107109 */
108 public String getName();
110 String getName();
109111 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
113113 }
114114 }
115115
116 private final Comparator comparator = new Comparator() {
117 public int compare(Object o1, Object o2) {
116 private final Comparator<ModuleRevisionId> comparator = new Comparator<ModuleRevisionId>() {
117 public int compare(ModuleRevisionId o1, ModuleRevisionId o2) {
118118 if (o1.equals(o2)) {
119119 return 0;
120120 }
121 ArtifactInfo art1 = new MRIDArtifactInfo((ModuleRevisionId) o1);
122 ArtifactInfo art2 = new MRIDArtifactInfo((ModuleRevisionId) o2);
123 ArtifactInfo art = getLatestStrategy()
124 .findLatest(new ArtifactInfo[] {art1, art2}, null);
121 ArtifactInfo art1 = new MRIDArtifactInfo(o1);
122 ArtifactInfo art2 = new MRIDArtifactInfo(o2);
123 ArtifactInfo art = getLatestStrategy().findLatest(new ArtifactInfo[] {art1, art2},
124 null);
125125 return art == art1 ? -1 : 1;
126126 }
127127 };
186186 }
187187
188188 public int compare(ModuleRevisionId askedMrid, ModuleRevisionId foundMrid,
189 Comparator staticComparator) {
189 Comparator<ModuleRevisionId> staticComparator) {
190190 String revision = askedMrid.getRevision();
191191 Matcher m;
192192 m = UPPER_INFINITE_RANGE.matcher(revision);
209209 }
210210 int c = staticComparator.compare(ModuleRevisionId.newInstance(askedMrid, upper), foundMrid);
211211 // if the comparison consider them equal, we must return -1, because we can't consider the
212 // dynamic revision to be greater. Otherwise we can safeely return the result of the static
212 // dynamic revision to be greater. Otherwise we can safely return the result of the static
213213 // comparison
214214 return c == 0 ? -1 : c;
215215 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
2020
2121 public interface DependencyAnalyser {
22 public ModuleDescriptor[] analyze(JarModule[] modules);
22 ModuleDescriptor[] analyze(JarModule[] modules);
2323 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727 import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
2828 import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
2929 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
30 import org.apache.ivy.core.module.id.ModuleRevisionId;
3031 import org.apache.ivy.util.Message;
3132
3233 public class JarJarDependencyAnalyser implements DependencyAnalyser {
3738 }
3839
3940 public ModuleDescriptor[] analyze(JarModule[] modules) {
41 StringBuilder jarjarCmd = new StringBuilder("java -jar \"").append(
42 jarjarjarLocation.getAbsolutePath()).append("\" --find --level=jar ");
43 Map<String, JarModule> jarModulesMap = new HashMap<>();
44 Map<ModuleRevisionId, DefaultModuleDescriptor> mds = new HashMap<>();
4045
41 StringBuffer jarjarCmd = new StringBuffer("java -jar \"").append(
42 jarjarjarLocation.getAbsolutePath()).append("\" --find --level=jar ");
43 Map jarModulesMap = new HashMap();
44 Map mds = new HashMap();
46 for (JarModule jarModule : modules) {
47 jarModulesMap.put(jarModule.getJar().getAbsolutePath(), jarModule);
48 DefaultModuleDescriptor md = DefaultModuleDescriptor.newBasicInstance(
49 jarModule.getMrid(), new Date(jarModule.getJar().lastModified()));
50 mds.put(jarModule.getMrid(), md);
51 jarjarCmd.append("\"").append(jarModule.getJar().getAbsolutePath()).append("\"");
52 jarjarCmd.append(File.pathSeparator);
53 }
4554
46 for (int i = 0; i < modules.length; i++) {
47 jarModulesMap.put(modules[i].getJar().getAbsolutePath(), modules[i]);
48 DefaultModuleDescriptor md = DefaultModuleDescriptor.newBasicInstance(
49 modules[i].getMrid(), new Date(modules[i].getJar().lastModified()));
50 mds.put(modules[i].getMrid(), md);
51 jarjarCmd.append("\"").append(modules[i].getJar().getAbsolutePath()).append("\"");
52 if (i + 1 < modules.length) {
53 jarjarCmd.append(File.pathSeparator);
54 }
55 if (modules.length > 0) {
56 jarjarCmd.setLength(jarjarCmd.length() - 1);
5557 }
5658
5759 Message.verbose("jarjar command: " + jarjarCmd);
6264 String line;
6365 while ((line = r.readLine()) != null) {
6466 String[] deps = line.split(" -> ");
65 JarModule module = (JarModule) jarModulesMap.get(deps[0]);
66 JarModule dependency = (JarModule) jarModulesMap.get(deps[1]);
67 JarModule module = jarModulesMap.get(deps[0]);
68 JarModule dependency = jarModulesMap.get(deps[1]);
6769
6870 if (module.getMrid().getModuleId().equals(dependency.getMrid().getModuleId())) {
6971 continue;
7072 }
7173 Message.verbose(module.getMrid() + " depends on " + dependency.getMrid());
7274
73 DefaultModuleDescriptor md = (DefaultModuleDescriptor) mds.get(module.getMrid());
75 DefaultModuleDescriptor md = mds.get(module.getMrid());
7476
7577 DefaultDependencyDescriptor dd = new DefaultDependencyDescriptor(md,
7678 dependency.getMrid(), false, false, true);
8183 } catch (IOException e) {
8284 Message.debug(e);
8385 }
84 return (ModuleDescriptor[]) mds.values().toArray(new ModuleDescriptor[mds.values().size()]);
86 return mds.values().toArray(new ModuleDescriptor[mds.values().size()]);
8587 }
8688
8789 public static void main(String[] args) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3838 }
3939
4040 public JarModule[] findJarModules() {
41 List ret = new ArrayList();
41 List<JarModule> ret = new ArrayList<>();
4242 URLLister lister = new FileURLLister();
4343 try {
44 String[] orgs = ResolverHelper.listTokenValues(lister, pattern, "organisation");
45 for (int i = 0; i < orgs.length; i++) {
44 for (String org : ResolverHelper.listTokenValues(lister, pattern, "organisation")) {
4645 String orgPattern = IvyPatternHelper.substituteToken(pattern,
47 IvyPatternHelper.ORGANISATION_KEY, orgs[i]);
48 String[] modules = ResolverHelper.listTokenValues(lister, orgPattern, "module");
49 for (int j = 0; j < modules.length; j++) {
46 IvyPatternHelper.ORGANISATION_KEY, org);
47 for (String module : ResolverHelper.listTokenValues(lister, orgPattern, "module")) {
5048 String modPattern = IvyPatternHelper.substituteToken(orgPattern,
51 IvyPatternHelper.MODULE_KEY, modules[j]);
52 String[] revs = ResolverHelper.listTokenValues(lister, modPattern, "revision");
53 for (int k = 0; k < revs.length; k++) {
54 File jar = new File(IvyPatternHelper.substitute(filePattern, orgs[i],
55 modules[j], revs[k], modules[j], "jar", "jar"));
49 IvyPatternHelper.MODULE_KEY, module);
50 for (String rev : ResolverHelper.listTokenValues(lister, modPattern, "revision")) {
51 File jar = new File(IvyPatternHelper.substitute(filePattern, org,
52 module, rev, module, "jar", "jar"));
5653 if (jar.exists()) {
57 ret.add(new JarModule(ModuleRevisionId.newInstance(orgs[i], modules[j],
58 revs[k]), jar));
54 ret.add(new JarModule(ModuleRevisionId.newInstance(org, module, rev), jar));
5955 }
6056 }
6157 }
6561 Message.debug(e);
6662 // TODO: handle exception
6763 }
68 return (JarModule[]) ret.toArray(new JarModule[ret.size()]);
64 return ret.toArray(new JarModule[ret.size()]);
6965 }
7066
7167 public static void main(String[] args) {
7268 JarModule[] mods = new JarModuleFinder(
7369 "D:/temp/test2/ivyrep/[organisation]/[module]/[revision]/[artifact].[ext]")
7470 .findJarModules();
75 for (int i = 0; i < mods.length; i++) {
76 System.out.println(mods[i]);
71 for (JarModule mod : mods) {
72 System.out.println(mod);
7773 }
7874 }
7975 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3030 JarModuleFinder finder = new JarModuleFinder(pattern);
3131 ModuleDescriptor[] mds = depAnalyser.analyze(finder.findJarModules());
3232 Message.info("found " + mds.length + " modules");
33 for (int i = 0; i < mds.length; i++) {
33 for (ModuleDescriptor md : mds) {
3434 File ivyFile = new File(IvyPatternHelper.substitute(
35 pattern,
36 DefaultArtifact.newIvyArtifact(mds[i].getModuleRevisionId(),
37 mds[i].getPublicationDate())));
35 pattern,
36 DefaultArtifact.newIvyArtifact(md.getModuleRevisionId(),
37 md.getPublicationDate())));
3838 try {
3939 Message.info("generating " + ivyFile);
40 XmlModuleDescriptorWriter.write(mds[i], ivyFile);
40 XmlModuleDescriptorWriter.write(md, ivyFile);
4141 } catch (IOException e) {
4242 Message.debug(e);
4343 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 * An abstract base class to ease {@link MessageLogger} implementation.
2424 */
2525 public abstract class AbstractMessageLogger implements MessageLogger {
26 private List problems = new ArrayList();
26 private List<String> problems = new ArrayList<>();
2727
28 private List warns = new ArrayList();
28 private List<String> warns = new ArrayList<>();
2929
30 private List errors = new ArrayList();
30 private List<String> errors = new ArrayList<>();
3131
3232 private boolean showProgress = true;
3333
34 /*
35 * (non-Javadoc)
36 *
37 * @see org.apache.ivy.util.MessageLogger#debug(java.lang.String)
38 */
3934 public void debug(String msg) {
4035 log(msg, Message.MSG_DEBUG);
4136 }
4237
43 /*
44 * (non-Javadoc)
45 *
46 * @see org.apache.ivy.util.MessageLogger#verbose(java.lang.String)
47 */
4838 public void verbose(String msg) {
4939 log(msg, Message.MSG_VERBOSE);
5040 }
5141
52 /*
53 * (non-Javadoc)
54 *
55 * @see org.apache.ivy.util.MessageLogger#deprecated(java.lang.String)
56 */
5742 public void deprecated(String msg) {
5843 log("DEPRECATED: " + msg, Message.MSG_WARN);
5944 }
6045
61 /*
62 * (non-Javadoc)
63 *
64 * @see org.apache.ivy.util.MessageLogger#info(java.lang.String)
65 */
6646 public void info(String msg) {
6747 log(msg, Message.MSG_INFO);
6848 }
6949
70 /*
71 * (non-Javadoc)
72 *
73 * @see org.apache.ivy.util.MessageLogger#info(java.lang.String)
74 */
7550 public void rawinfo(String msg) {
7651 rawlog(msg, Message.MSG_INFO);
7752 }
7853
79 /*
80 * (non-Javadoc)
81 *
82 * @see org.apache.ivy.util.MessageLogger#warn(java.lang.String)
83 */
8454 public void warn(String msg) {
8555 log("WARN: " + msg, Message.MSG_VERBOSE);
8656 problems.add("WARN: " + msg);
8757 getWarns().add(msg);
8858 }
8959
90 /*
91 * (non-Javadoc)
92 *
93 * @see org.apache.ivy.util.MessageLogger#error(java.lang.String)
94 */
9560 public void error(String msg) {
9661 // log in verbose mode because message is appended as a problem, and will be
9762 // logged at the end at error level
10065 getErrors().add(msg);
10166 }
10267
103 /*
104 * (non-Javadoc)
105 *
106 * @see org.apache.ivy.util.MessageLogger#getProblems()
107 */
108 public List getProblems() {
68 public List<String> getProblems() {
10969 return problems;
11070 }
11171
112 /*
113 * (non-Javadoc)
114 *
115 * @see org.apache.ivy.util.MessageLogger#sumupProblems()
116 */
11772 public void sumupProblems() {
11873 MessageLoggerHelper.sumupProblems(this);
11974 clearProblems();
12580 errors.clear();
12681 }
12782
128 public List getErrors() {
83 public List<String> getErrors() {
12984 return errors;
13085 }
13186
132 public List getWarns() {
87 public List<String> getWarns() {
13388 return warns;
13489 }
13590
136 /*
137 * (non-Javadoc)
138 *
139 * @see org.apache.ivy.util.MessageLogger#progress()
140 */
14191 public void progress() {
14292 if (showProgress) {
14393 doProgress();
14494 }
14595 }
14696
147 /*
148 * (non-Javadoc)
149 *
150 * @see org.apache.ivy.util.MessageLogger#endProgress()
151 */
15297 public void endProgress() {
15398 endProgress("");
15499 }
155100
156 /*
157 * (non-Javadoc)
158 *
159 * @see org.apache.ivy.util.MessageLogger#endProgress(java.lang.String)
160 */
161101 public void endProgress(String msg) {
162102 if (showProgress) {
163103 doEndProgress(msg);
164104 }
165105 }
166106
167 /*
168 * (non-Javadoc)
169 *
170 * @see org.apache.ivy.util.MessageLogger#isShowProgress()
171 */
172107 public boolean isShowProgress() {
173108 return showProgress;
174109 }
175110
176 /*
177 * (non-Javadoc)
178 *
179 * @see org.apache.ivy.util.MessageLogger#setShowProgress(boolean)
180 */
181111 public void setShowProgress(boolean progress) {
182112 showProgress = progress;
183113 }
189119
190120 /**
191121 * Indicates the end of a long running task
192 *
122 *
193123 * @param msg
194124 * the message associated with long running task end.
195125 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2727
2828 /**
2929 * Checks that an object is not null, and throw an exception if the object is null.
30 *
30 *
3131 * @param o
3232 * the object to check
3333 * @param objectName
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3232
3333 private static final int BUFFER_SIZE = 2048;
3434
35 private static Map algorithms = new HashMap();
35 private static final Map<String, String> algorithms = new HashMap<>();
3636 static {
3737 algorithms.put("md5", "MD5");
3838 algorithms.put("sha1", "SHA-1");
39
40 // higher versions of JRE support these algorithms
41 // https://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html#MessageDigest
42 // conditionally add them
43 if (isAlgorithmSupportedInJRE("SHA-256")) {
44 algorithms.put("SHA-256", "SHA-256");
45 }
46 if (isAlgorithmSupportedInJRE("SHA-512")) {
47 algorithms.put("SHA-512", "SHA-512");
48 }
49 if (isAlgorithmSupportedInJRE("SHA-384")) {
50 algorithms.put("SHA-384", "SHA-384");
51 }
52
53 }
54
55 private static boolean isAlgorithmSupportedInJRE(final String algorithm) {
56 if (algorithm == null) {
57 return false;
58 }
59 try {
60 MessageDigest.getInstance(algorithm);
61 return true;
62 } catch (NoSuchAlgorithmException e) {
63 return false;
64 }
3965 }
4066
4167 /**
4268 * Checks the checksum of the given file against the given checksumFile, and throws an
4369 * IOException if the checksum is not compliant
44 *
70 *
4571 * @param dest
4672 * the file to test
4773 * @param checksumFile
4975 * @param algorithm
5076 * the checksum algorithm to use
5177 * @throws IOException
52 * if an IO problem occur whle reading files or if the checksum is not compliant
78 * if an IO problem occur while reading files or if the checksum is not compliant
5379 */
5480 public static void check(File dest, File checksumFile, String algorithm) throws IOException {
5581 String csFileContent = FileUtil
6894 // IVY-1155: support some strange formats like this one:
6995 // https://repo1.maven.org/maven2/org/apache/pdfbox/fontbox/0.8.0-incubator/fontbox-0.8.0-incubator.jar.md5
7096 if (expected.endsWith(":")) {
71 StringBuffer result = new StringBuffer();
72 char[] chars = csFileContent.substring(spaceIndex + 1).toCharArray();
73 for (int i = 0; i < chars.length; i++) {
74 if (!Character.isWhitespace(chars[i])) {
75 result.append(chars[i]);
97 StringBuilder result = new StringBuilder();
98 for (char ch : csFileContent.substring(spaceIndex + 1).toCharArray()) {
99 if (!Character.isWhitespace(ch)) {
100 result.append(ch);
76101 }
77102 }
78103 expected = result.toString();
94119 }
95120
96121 private static byte[] compute(File f, String algorithm) throws IOException {
97 InputStream is = new FileInputStream(f);
98122
99 try {
123 try (InputStream is = new FileInputStream(f)) {
100124 MessageDigest md = getMessageDigest(algorithm);
101125 md.reset();
102126
106130 md.update(buf, 0, len);
107131 }
108132 return md.digest();
109 } finally {
110 is.close();
111133 }
112134 }
113135
116138 }
117139
118140 private static MessageDigest getMessageDigest(String algorithm) {
119 String mdAlgorithm = (String) algorithms.get(algorithm);
141 String mdAlgorithm = algorithms.get(algorithm);
120142 if (mdAlgorithm == null) {
121143 throw new IllegalArgumentException("unknown algorithm " + algorithm);
122144 }
133155
134156 /**
135157 * Convert a byte[] array to readable string format. This makes the "hex" readable!
136 *
158 *
137159 * @return result String buffer in String format
138160 * @param in
139161 * byte[] buffer to convert to string format
145167 return null;
146168 }
147169
148 StringBuffer out = new StringBuffer(in.length * 2);
170 StringBuilder out = new StringBuilder(in.length * 2);
149171
150172 // CheckStyle:MagicNumber OFF
151 for (int i = 0; i < in.length; i++) {
152 ch = (byte) (in[i] & 0xF0); // Strip off high nibble
173 for (byte bt : in) {
174 ch = (byte) (bt & 0xF0); // Strip off high nibble
153175 ch = (byte) (ch >>> 4); // shift the bits down
154176 ch = (byte) (ch & 0x0F); // must do this is high order bit is on!
155177
156178 out.append(CHARS[ch]); // convert the nibble to a String Character
157 ch = (byte) (in[i] & 0x0F); // Strip off low nibble
179 ch = (byte) (bt & 0x0F); // Strip off low nibble
158180 out.append(CHARS[ch]); // convert the nibble to a String Character
159181 }
160182 // CheckStyle:MagicNumber ON
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222
2323 public class CollectionUtils {
2424
25 public static List toList(Iterator iterator) {
26 List list = new ArrayList();
25 public static <T> List<T> toList(Iterator<T> iterator) {
26 List<T> list = new ArrayList<>();
2727 while (iterator.hasNext()) {
2828 list.add(iterator.next());
2929 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.util;
1818
1919 import java.util.Arrays;
20 import java.util.Iterator;
2120 import java.util.LinkedHashSet;
2221 import java.util.Set;
2322
2423 import org.apache.ivy.core.module.descriptor.Configuration;
25 import org.apache.ivy.core.module.descriptor.Configuration.Visibility;
2624 import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
25
26 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PRIVATE;
27 import static org.apache.ivy.core.module.descriptor.Configuration.Visibility.PUBLIC;
2728
2829 /**
2930 * Class containing several utility methods for working with configurations.
3940 /**
4041 * Replace the wildcards in the given configuration array, by the name of the given
4142 * ModuleDescriptor
42 *
43 *
4344 * The supported wildcards are:
4445 * <ul>
4546 * <li><b><tt>*</tt> :</b> all configurations</li>
4849 * </ul>
4950 * If the given array of configurations is <code>null</code>, all configurations from the given
5051 * module descriptor are returned, including if this array is empty.
51 *
52 *
5253 * @param confs
5354 * the configurations, can contain wildcards
5455 * @param md
5556 * the configurations where the wildcards are replaced
56 * @return
57 * @return configurations
5758 */
5859 public static String[] replaceWildcards(String[] confs, ModuleDescriptor md) {
5960 if (confs == null) {
6061 return md.getConfigurationsNames();
6162 }
6263
63 Set result = new LinkedHashSet();
64 Set excluded = new LinkedHashSet();
65 for (int i = 0; i < confs.length; i++) {
66 if ("*".equals(confs[i])) {
64 Set<String> result = new LinkedHashSet<>();
65 Set<String> excluded = new LinkedHashSet<>();
66 for (String conf : confs) {
67 if ("*".equals(conf)) {
6768 result.addAll(Arrays.asList(md.getConfigurationsNames()));
68 } else if ("*(public)".equals(confs[i])) {
69 Configuration[] all = md.getConfigurations();
70 for (int j = 0; j < all.length; j++) {
71 if (all[j].getVisibility().equals(Visibility.PUBLIC)) {
72 result.add(all[j].getName());
69 } else if ("*(public)".equals(conf)) {
70 for (Configuration cf : md.getConfigurations()) {
71 if (PUBLIC.equals(cf.getVisibility())) {
72 result.add(cf.getName());
7373 }
7474 }
75 } else if ("*(private)".equals(confs[i])) {
76 Configuration[] all = md.getConfigurations();
77 for (int j = 0; j < all.length; j++) {
78 if (all[j].getVisibility().equals(Visibility.PRIVATE)) {
79 result.add(all[j].getName());
75 } else if ("*(private)".equals(conf)) {
76 for (Configuration cf : md.getConfigurations()) {
77 if (PRIVATE.equals(cf.getVisibility())) {
78 result.add(cf.getName());
8079 }
8180 }
82 } else if (confs[i].startsWith("!")) {
83 excluded.add(confs[i].substring(1));
81 } else if (conf.startsWith("!")) {
82 excluded.add(conf.substring(1));
8483 } else {
85 result.add(confs[i]);
84 result.add(conf);
8685 }
8786 }
88 for (Iterator iter = excluded.iterator(); iter.hasNext();) {
89 result.remove(iter.next());
87 for (String ex : excluded) {
88 result.remove(ex);
9089 }
9190
92 return (String[]) result.toArray(new String[result.size()]);
91 return result.toArray(new String[result.size()]);
9392 }
9493
9594 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2323 import java.util.Arrays;
2424 import java.util.Collections;
2525 import java.util.HashMap;
26 import java.util.Iterator;
2726 import java.util.LinkedHashMap;
2827 import java.util.List;
2928 import java.util.Map;
3736 * This configurator is used to configure elements (initialised with setRoot) using the behaviour
3837 * defined by ant for its tasks.
3938 * <p>
40 * Example (based on <a href="http://ant.apache.org/manual/develop.html#writingowntask">Ant
39 * Example (based on <a href="https://ant.apache.org/manual/develop.html#writingowntask">Ant
4140 * Example</a>):
42 *
41 *
4342 * <pre>
4443 * Configurator conf = new Configurator();
4544 * conf.typeDef(&quot;buildpath&quot;, &quot;Sample$BuildPath&quot;);
5958 public static class Macro {
6059 private MacroDef macrodef;
6160
62 private Map attValues = new HashMap();
63
64 private Map macroRecords = new HashMap();
61 private Map<String, String> attValues = new HashMap<>();
62
63 private Map<String, List<MacroRecord>> macroRecords = new HashMap<>();
6564
6665 public Macro(MacroDef def) {
6766 macrodef = def;
7776
7877 public MacroRecord recordCreateChild(String name) {
7978 MacroRecord macroRecord = new MacroRecord(name);
80 List records = (List) macroRecords.get(name);
79 List<MacroRecord> records = macroRecords.get(name);
8180 if (records == null) {
82 records = new ArrayList();
81 records = new ArrayList<>();
8382 macroRecords.put(name, records);
8483 }
8584 records.add(macroRecord);
139138 public static class MacroRecord {
140139 private String name;
141140
142 private Map attributes = new LinkedHashMap();
143
144 private List children = new ArrayList();
141 private Map<String, String> attributes = new LinkedHashMap<>();
142
143 private List<MacroRecord> children = new ArrayList<>();
145144
146145 private Object object;
147146
169168 return child;
170169 }
171170
172 public Map getAttributes() {
171 public Map<String, String> getAttributes() {
173172 return attributes;
174173 }
175174
176 public List getChildren() {
175 public List<MacroRecord> getChildren() {
177176 return children;
178177 }
179178
185184 public static class MacroDef {
186185 private String name;
187186
188 private Map attributes = new HashMap();
189
190 private Map elements = new HashMap();
187 private Map<String, Attribute> attributes = new HashMap<>();
188
189 private Map<String, Element> elements = new HashMap<>();
191190
192191 private MacroRecord macroRecord;
193192
196195 }
197196
198197 public Attribute getAttribute(String attributeName) {
199 return (Attribute) attributes.get(attributeName);
200 }
201
202 public Object play(Configurator conf, Map attValues, Map macroRecords) {
203 for (Iterator iter = attributes.values().iterator(); iter.hasNext();) {
204 Attribute att = (Attribute) iter.next();
205 String val = (String) attValues.get(att.getName());
198 return attributes.get(attributeName);
199 }
200
201 public Object play(Configurator conf, Map<String, String> attValues,
202 Map<String, List<MacroRecord>> macroRecords) {
203 for (Attribute att : attributes.values()) {
204 String val = attValues.get(att.getName());
206205 if (val == null) {
207206 if (att.getDefault() == null) {
208207 throw new IllegalArgumentException("attribute " + att.getName()
215214 return play(conf, macroRecord, attValues, macroRecords);
216215 }
217216
218 private Object play(Configurator conf, MacroRecord macroRecord, Map attValues,
219 Map childrenRecords) {
217 private Object play(Configurator conf, MacroRecord macroRecord, Map<String, String> attValues,
218 Map<String, List<MacroRecord>> childrenRecords) {
220219 if (macroRecord.getObject() != null) {
221220 // this is a recorded reference, we can add the referenced object directly
222221 conf.addChild(macroRecord.getName(), macroRecord.getObject());
224223 return macroRecord.getObject();
225224 }
226225 conf.startCreateChild(macroRecord.getName());
227 Map attributes = macroRecord.getAttributes();
228 for (Iterator iter = attributes.keySet().iterator(); iter.hasNext();) {
229 String attName = (String) iter.next();
230 String attValue = replaceParam((String) attributes.get(attName), attValues);
231 conf.setAttribute(attName, attValue);
232 }
233 for (Iterator iter = macroRecord.getChildren().iterator(); iter.hasNext();) {
234 MacroRecord child = (MacroRecord) iter.next();
235 Element elt = (Element) elements.get(child.getName());
226 for (Map.Entry<String, String> attribute : macroRecord.getAttributes().entrySet()) {
227 conf.setAttribute(attribute.getKey(), replaceParam(attribute.getValue(), attValues));
228 }
229 for (MacroRecord child : macroRecord.getChildren()) {
230 Element elt = elements.get(child.getName());
236231 if (elt != null) {
237 List elements = (List) childrenRecords.get(child.getName());
232 List<MacroRecord> elements = childrenRecords.get(child.getName());
238233 if (elements != null) {
239 for (Iterator iterator = elements.iterator(); iterator.hasNext();) {
240 MacroRecord element = (MacroRecord) iterator.next();
241 for (Iterator it2 = element.getChildren().iterator(); it2.hasNext();) {
242 MacroRecord r = (MacroRecord) it2.next();
243 play(conf, r, attValues, Collections.EMPTY_MAP);
234 for (MacroRecord element : elements) {
235 for (MacroRecord r : element.getChildren()) {
236 play(conf, r, attValues, Collections.<String, List<MacroRecord>>emptyMap());
244237 }
245238 }
246239 } else if (!elt.isOptional()) {
255248 return conf.endCreateChild();
256249 }
257250
258 private String replaceParam(String string, Map attValues) {
251 private String replaceParam(String string, Map<String, String> attValues) {
259252 return IvyPatternHelper.substituteParams(string, attValues);
260253 }
261254
300293
301294 private String objName;
302295
303 private Map createMethods = new HashMap();
304
305 private Map addMethods = new HashMap();
306
307 private Map addConfiguredMethods = new HashMap();
308
309 private Map setMethods = new HashMap();
310
311 private Map typeAddMethods = new HashMap();
312
313 private Map typeAddConfiguredMethods = new HashMap();
296 private Map<String, Method> createMethods = new HashMap<>();
297
298 private Map<String, Method> addMethods = new HashMap<>();
299
300 private Map<String, Method> addConfiguredMethods = new HashMap<>();
301
302 private Map<String, Method> setMethods = new HashMap<>();
303
304 private Map<Class<?>, Method> typeAddMethods = new HashMap<>();
305
306 private Map<Class<?>, Method> typeAddConfiguredMethods = new HashMap<>();
314307
315308 public ObjectDescriptor(Object object, String objName) {
316309 obj = object;
317310 this.objName = objName;
318 Method[] methods = object.getClass().getMethods();
319 for (int i = 0; i < methods.length; i++) {
320 Method m = methods[i];
311 for (Method m : object.getClass().getMethods()) {
321312 if (m.getName().startsWith("create") && m.getParameterTypes().length == 0
322313 && !Void.TYPE.equals(m.getReturnType())) {
323314 String name = StringUtils
329320 } else if (m.getName().startsWith("addConfigured")
330321 && m.getParameterTypes().length == 1 && Void.TYPE.equals(m.getReturnType())) {
331322 String name = StringUtils.uncapitalize(m.getName().substring(
332 "addConfigured".length()));
323 "addConfigured".length()));
333324 if (name.length() == 0) {
334325 addAddConfiguredMethod(m);
335326 }
374365 }
375366
376367 public void addSetMethod(String name, Method m) {
377 Method current = (Method) setMethods.get(name);
368 Method current = setMethods.get(name);
378369 if (current != null && current.getParameterTypes()[0] == String.class) {
379370 // setter methods with String attribute take precedence
380371 return;
387378 }
388379
389380 public Method getCreateMethod(String name) {
390 return (Method) createMethods.get(name);
381 return createMethods.get(name);
391382 }
392383
393384 public Method getAddMethod(String name) {
394 return (Method) addMethods.get(name);
385 return addMethods.get(name);
395386 }
396387
397388 public Method getAddConfiguredMethod(String name) {
398 return (Method) addConfiguredMethods.get(name);
399 }
400
401 public Method getAddMethod(Class type) {
389 return addConfiguredMethods.get(name);
390 }
391
392 public Method getAddMethod(Class<?> type) {
402393 return getTypeMatchingMethod(type, typeAddMethods);
403394 }
404395
405 public Method getAddConfiguredMethod(Class type) {
396 public Method getAddConfiguredMethod(Class<?> type) {
406397 return getTypeMatchingMethod(type, typeAddConfiguredMethods);
407398 }
408399
409 private Method getTypeMatchingMethod(Class type, Map typeMethods) {
410 Method m = (Method) typeMethods.get(type);
400 private Method getTypeMatchingMethod(Class<?> type, Map<Class<?>, Method> typeMethods) {
401 Method m = typeMethods.get(type);
411402 if (m != null) {
412403 return m;
413404 }
414 for (Iterator iter = typeMethods.keySet().iterator(); iter.hasNext();) {
415 Class clss = (Class) iter.next();
416 if (clss.isAssignableFrom(type)) {
417 return (Method) typeMethods.get(clss);
405 for (Map.Entry<Class<?>, Method> method : typeMethods.entrySet()) {
406 if (method.getKey().isAssignableFrom(type)) {
407 return method.getValue();
418408 }
419409 }
420410 return null;
421411 }
422412
423413 public Method getSetMethod(String name) {
424 return (Method) setMethods.get(name);
414 return setMethods.get(name);
425415 }
426416
427417 public String getObjectName() {
431421
432422 private FileResolver fileResolver = FileResolver.DEFAULT;
433423
434 private Map typedefs = new HashMap();
435
436 private Map macrodefs = new HashMap();
424 private Map<String, Class<?>> typedefs = new HashMap<>();
425
426 private Map<String, MacroDef> macrodefs = new HashMap<>();
437427
438428 // stack in which the top is current configured object descriptor
439 private Stack objectStack = new Stack();
440
441 private static final List TRUE_VALUES = Arrays.asList(new String[] {"true", "yes", "on"});
429 private Stack<ObjectDescriptor> objectStack = new Stack<>();
430
431 private static final List<String> TRUE_VALUES = Arrays.asList("true", "yes", "on");
442432
443433 public void typeDef(String name, String className) throws ClassNotFoundException {
444434 typeDef(name, Class.forName(className));
445435 }
446436
447 public void typeDef(String name, Class clazz) {
437 public void typeDef(String name, Class<?> clazz) {
448438 typedefs.put(name, clazz);
449439 }
450440
468458 if (objectStack.isEmpty()) {
469459 throw new IllegalStateException("set root before creating child");
470460 }
471 ObjectDescriptor parentOD = (ObjectDescriptor) objectStack.peek();
461 ObjectDescriptor parentOD = objectStack.peek();
472462 Object parent = parentOD.getObject();
473463 if (parent instanceof MacroDef) {
474464 if (!"attribute".equals(name) && !"element".equals(name)) {
488478 return record;
489479 }
490480 Object child = null;
491 MacroDef macrodef = (MacroDef) macrodefs.get(name);
481 MacroDef macrodef = macrodefs.get(name);
492482 if (macrodef != null) {
493483 Macro macro = macrodef.createMacro();
494484 setCurrent(macro, name);
495485 return macro;
496486 }
497 Class childClass = (Class) typedefs.get(name);
487 Class<?> childClass = typedefs.get(name);
498488 Method addChild = null;
499489 try {
500490 if (childClass != null) {
502492 } else {
503493 addChild = parentOD.getCreateMethod(name);
504494 if (addChild != null) {
505 child = addChild.invoke(parent, new Object[0]);
495 child = addChild.invoke(parent);
506496 setCurrent(child, name);
507497 return child;
508498 }
510500 if (addChild != null) {
511501 childClass = addChild.getParameterTypes()[0];
512502 child = childClass.newInstance();
513 addChild.invoke(parent, new Object[] {child});
503 addChild.invoke(parent, child);
514504 setCurrent(child, name);
515505 return child;
516506 }
518508 if (addChild != null) {
519509 childClass = addChild.getParameterTypes()[0];
520510 if (Map.class == childClass) {
521 child = new HashMap();
511 child = new HashMap<>();
522512 } else {
523513 child = childClass.newInstance();
524514 }
530520 throw new IllegalArgumentException("no default constructor on " + childClass
531521 + " for adding " + name + " on " + parent.getClass());
532522 } catch (Exception ex) {
533 IllegalArgumentException iae = new IllegalArgumentException("bad method found for "
534 + name + " on " + parent.getClass());
535 iae.initCause(ex);
536 throw iae;
523 throw new IllegalArgumentException("bad method found for " + name + " on "
524 + parent.getClass(), ex);
537525 }
538526 throw new IllegalArgumentException("no appropriate method found for adding " + name
539527 + " on " + parent.getClass());
543531 if (objectStack.isEmpty()) {
544532 throw new IllegalStateException("set root before creating child");
545533 }
546 ObjectDescriptor parentOD = (ObjectDescriptor) objectStack.peek();
534 ObjectDescriptor parentOD = objectStack.peek();
547535 try {
548536 addChild(parentOD, child.getClass(), name, child);
549537 } catch (InstantiationException ex) {
550538 throw new IllegalArgumentException("no default constructor on " + child.getClass()
551539 + " for adding " + name + " on " + parentOD.getObject().getClass());
552540 } catch (Exception ex) {
553 IllegalArgumentException iae = new IllegalArgumentException("bad method found for "
554 + name + " on " + parentOD.getObject().getClass());
555 iae.initCause(ex);
556 throw iae;
557 }
558 }
559
560 private Object addChild(ObjectDescriptor parentOD, Class childClass, String name, Object child)
541 throw new IllegalArgumentException("bad method found for "
542 + name + " on " + parentOD.getObject().getClass(), ex);
543 }
544 }
545
546 private Object addChild(ObjectDescriptor parentOD, Class<?> childClass, String name,
547 Object child)
561548 throws InstantiationException, IllegalAccessException, InvocationTargetException {
562549 Object parent = parentOD.getObject();
563550 if (parent instanceof MacroRecord) {
571558 if (child == null) {
572559 child = childClass.newInstance();
573560 }
574 addChild.invoke(parent, new Object[] {child});
561 addChild.invoke(parent, child);
575562 setCurrent(child, name);
576563 return child;
577564 }
579566 if (addChild != null) {
580567 if (child == null) {
581568 if (Map.class == childClass) {
582 child = new HashMap();
569 child = new HashMap<>();
583570 } else {
584571 child = childClass.newInstance();
585572 }
595582 if (objectStack.isEmpty()) {
596583 return false;
597584 }
598 ObjectDescriptor od = (ObjectDescriptor) objectStack.peek();
585 ObjectDescriptor od = objectStack.peek();
599586 return (od.getObject() instanceof MacroDef);
600587 }
601588
589 @SuppressWarnings("unchecked")
602590 public void setAttribute(String attributeName, String value) {
603591 if (objectStack.isEmpty()) {
604592 throw new IllegalStateException("set root before setting attribute");
605593 }
606 ObjectDescriptor od = (ObjectDescriptor) objectStack.peek();
594 ObjectDescriptor od = objectStack.peek();
607595 if (od.getObject() instanceof Macro) {
608596 ((Macro) od.getObject()).defineAttribute(attributeName, value);
609597 return;
615603 Method m = od.getSetMethod(attributeName);
616604 if (m == null) {
617605 if (od.getObject() instanceof Map) {
618 ((Map) od.getObject()).put(attributeName, value);
606 ((Map<String, String>) od.getObject()).put(attributeName, value);
619607 return;
620608 }
621609 throw new IllegalArgumentException("no set method found for " + attributeName + " on "
622610 + od.getObject().getClass());
623611 }
624612 Object convertedValue = null;
625 Class paramClass = m.getParameterTypes()[0];
613 Class<?> paramClass = m.getParameterTypes()[0];
626614 try {
627615 if (paramClass.equals(String.class)) {
628616 convertedValue = value;
629617 } else if (paramClass.equals(Boolean.class) || paramClass.equals(boolean.class)) {
630 convertedValue = Boolean.valueOf(TRUE_VALUES.contains(value));
618 convertedValue = TRUE_VALUES.contains(value);
631619 } else if (paramClass.equals(Character.class) || paramClass.equals(char.class)) {
632 convertedValue = new Character(value.length() > 0 ? value.charAt(0) : ' ');
620 convertedValue = value.length() > 0 ? value.charAt(0) : ' ';
633621 } else if (paramClass.equals(Short.class) || paramClass.equals(short.class)) {
634622 convertedValue = Short.valueOf(value);
635623 } else if (paramClass.equals(Integer.class) || paramClass.equals(int.class)) {
642630 convertedValue = fileResolver.resolveFile(value, od.getObjectName() + "."
643631 + attributeName);
644632 } else {
645 convertedValue = paramClass.getConstructor(new Class[] {String.class}).newInstance(
646 new Object[] {value});
633 convertedValue = paramClass.getConstructor(String.class).newInstance(value);
647634 }
648635 } catch (Exception ex) {
649 IllegalArgumentException iae = new IllegalArgumentException("impossible to convert "
636 throw new IllegalArgumentException("impossible to convert "
650637 + value + " to " + paramClass + " for setting " + attributeName + " on "
651 + od.getObject().getClass() + ": " + ex.getMessage());
652 iae.initCause(ex);
653 throw iae;
638 + od.getObject().getClass() + ": " + ex.getMessage(), ex);
654639 }
655640 try {
656 m.invoke(od.getObject(), new Object[] {convertedValue});
641 m.invoke(od.getObject(), convertedValue);
657642 } catch (Exception ex) {
658 IllegalArgumentException iae = new IllegalArgumentException("impossible to set "
659 + attributeName + " to " + convertedValue + " on " + od.getObject().getClass());
660 iae.initCause(ex);
661 throw iae;
643 throw new IllegalArgumentException("impossible to set " + attributeName + " to "
644 + convertedValue + " on " + od.getObject().getClass(), ex);
662645 }
663646 }
664647
666649 if (objectStack.isEmpty()) {
667650 throw new IllegalStateException("set root before adding text");
668651 }
669 ObjectDescriptor od = (ObjectDescriptor) objectStack.peek();
652 ObjectDescriptor od = objectStack.peek();
670653 try {
671 od.getObject().getClass().getMethod("addText", new Class[] {String.class})
672 .invoke(od.getObject(), new Object[] {text});
654 od.getObject().getClass().getMethod("addText", String.class)
655 .invoke(od.getObject(), text);
673656 } catch (Exception ex) {
674 IllegalArgumentException iae = new IllegalArgumentException(
675 "impossible to add text on " + od.getObject().getClass());
676 iae.initCause(ex);
677 throw iae;
657 throw new IllegalArgumentException("impossible to add text on "
658 + od.getObject().getClass(), ex);
678659 }
679660 }
680661
685666 if (objectStack.isEmpty()) {
686667 throw new IllegalStateException("set root before ending child");
687668 }
688 ObjectDescriptor od = (ObjectDescriptor) objectStack.pop();
669 ObjectDescriptor od = objectStack.pop();
689670 if (objectStack.isEmpty()) {
690671 objectStack.push(od); // back to previous state
691672 throw new IllegalStateException("cannot end root");
693674 if (od.getObject() instanceof Macro) {
694675 return ((Macro) od.getObject()).play(this);
695676 }
696 ObjectDescriptor parentOD = (ObjectDescriptor) objectStack.peek();
677 ObjectDescriptor parentOD = objectStack.peek();
697678 String name = od.getObjectName();
698 Class childClass = (Class) typedefs.get(name);
699 Method m = null;
700 if (childClass != null) {
701 m = parentOD.getAddConfiguredMethod(childClass);
702 } else {
703 m = parentOD.getAddConfiguredMethod(name);
704 }
679 Class<?> childClass = typedefs.get(name);
680 Method m = (childClass == null) ? parentOD.getAddConfiguredMethod(name)
681 : parentOD.getAddConfiguredMethod(childClass);
705682 try {
706683 if (m != null) {
707 m.invoke(parentOD.getObject(), new Object[] {od.getObject()});
684 m.invoke(parentOD.getObject(), od.getObject());
708685 }
709686 return od.getObject();
710687 } catch (Exception ex) {
711 IllegalArgumentException iae = new IllegalArgumentException(
688 throw new IllegalArgumentException(
712689 "impossible to add configured child for " + name + " on "
713690 + parentOD.getObject().getClass() + ": "
714 + StringUtils.getErrorMessage(ex));
715 iae.initCause(ex);
716 throw iae;
691 + StringUtils.getErrorMessage(ex), ex);
717692 }
718693 }
719694
720695 public Object getCurrent() {
721 return objectStack.isEmpty() ? null : ((ObjectDescriptor) objectStack.peek()).getObject();
696 return objectStack.isEmpty() ? null : objectStack.peek().getObject();
722697 }
723698
724699 public int getDepth() {
748723 macrodefs.put(macrodef.getName(), macrodef);
749724 }
750725
751 public Class getTypeDef(String name) {
752 return (Class) typedefs.get(name);
726 public Class<?> getTypeDef(String name) {
727 return typedefs.get(name);
753728 }
754729
755730 public FileResolver getFileResolver() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util;
1818
19 import java.util.Iterator;
2019 import java.util.Stack;
2120
2221 import org.xml.sax.Attributes;
2322 import org.xml.sax.SAXException;
2423 import org.xml.sax.helpers.DefaultHandler;
2524
25 import static org.apache.ivy.util.StringUtils.joinArray;
26
2627 public class ContextualSAXHandler extends DefaultHandler {
2728
28 private Stack contextStack = new Stack();
29 private Stack<String> contextStack = new Stack<>();
2930
30 private StringBuffer buffer = new StringBuffer();
31 private StringBuilder buffer = new StringBuilder();
3132
33 @Override
3234 public void characters(char[] ch, int start, int length) throws SAXException {
3335 buffer.append(ch, start, length);
3436 }
3537
38 @Override
3639 public void startElement(String uri, String localName, String qName, Attributes attributes)
3740 throws SAXException {
3841 contextStack.push(qName);
3942 buffer.setLength(0);
4043 }
4144
45 @Override
4246 public void endElement(String uri, String localName, String qName) throws SAXException {
4347 contextStack.pop();
4448 buffer.setLength(0);
4549 }
4650
4751 protected String getContext() {
48 StringBuffer buf = new StringBuffer();
49 for (Iterator iter = contextStack.iterator(); iter.hasNext();) {
50 String ctx = (String) iter.next();
51 buf.append(ctx).append("/");
52 }
53 if (buf.length() > 0) {
54 buf.setLength(buf.length() - 1);
55 }
56 return buf.toString();
52 return joinArray(contextStack.toArray(new String[contextStack.size()]), "/");
5753 }
5854
5955 protected String getText() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util;
1818
19 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
20 import static org.apache.ivy.util.StringUtils.repeat;
21
1922 /**
20 *
23 *
2124 */
2225 public class Credentials {
2326 private String realm;
5255 }
5356
5457 public static String buildKey(String realm, String host) {
55 if (realm == null || "".equals(realm.trim())) {
58 if (isNullOrEmpty(realm)) {
5659 return host;
57 } else {
58 return realm + "@" + host;
5960 }
61 return realm + "@" + host;
6062 }
6163
6264 /**
6365 * Return a string that can be used for debug purpose. It contains only stars for each password
6466 * character.
67 *
68 * @return String
6569 */
6670 public String toString() {
6771 return getKey() + " " + getUserName() + "/" + getPasswdAsStars();
7175 if (passwd == null) {
7276 return null;
7377 }
74 StringBuffer sb = new StringBuffer();
75 for (int i = passwd.length(); i > 0; i--) {
76 sb.append('*');
77 }
78 return sb.toString();
78 return repeat("*", passwd.length());
7979 }
8080
8181 public boolean equals(Object o) {
82 if (o == null) {
83 return false;
84 }
82 return o instanceof Credentials && getKey().equals(((Credentials) o).getKey());
8583
86 if (o instanceof Credentials) {
87 Credentials c = (Credentials) o;
88 return getKey().equals(c.getKey());
89 }
90
91 return false;
9284 }
9385
9486 public int hashCode() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3737
3838 public final class CredentialsUtil {
3939
40 @SuppressWarnings("serial")
4041 private static final class CredentialPanel extends JPanel {
4142 private static final int FIELD_LENGTH = 20;
4243
102103 CredentialPanel credentialPanel = new CredentialPanel(c, passfile);
103104 if (JOptionPane.showOptionDialog(null, credentialPanel, c.getHost() + " credentials",
104105 JOptionPane.OK_CANCEL_OPTION, 0, new ImageIcon(Ivy.class.getResource("logo.png")),
105 null, new Integer(JOptionPane.OK_OPTION)) == JOptionPane.OK_OPTION) {
106 null, JOptionPane.OK_OPTION) == JOptionPane.OK_OPTION) {
106107 String username = credentialPanel.userNameField.getText();
107108 String passwd = credentialPanel.passwordField.getText();
108109 if (credentialPanel.rememberDataCB.isSelected()) {
109 Properties props = new EncrytedProperties();
110 Properties props = new EncryptedProperties();
110111 props.setProperty("username", username);
111112 props.setProperty("passwd", passwd);
112 FileOutputStream fos = null;
113 try {
114 fos = new FileOutputStream(passfile);
113 try (FileOutputStream fos = new FileOutputStream(passfile)) {
115114 props.store(fos, "");
116115 } catch (Exception e) {
117116 Message.warn("error occurred while saving password file " + passfile, e);
118 } finally {
119 if (fos != null) {
120 try {
121 fos.close();
122 } catch (Exception e) {
123 // ignored
124 }
125 }
126117 }
127118 }
128119 c = new Credentials(c.getRealm(), c.getHost(), username, passwd);
132123
133124 public static Credentials loadPassfile(Credentials c, File passfile) {
134125 if (passfile != null && passfile.exists()) {
135 Properties props = new EncrytedProperties();
136 FileInputStream fis = null;
137 try {
138 fis = new FileInputStream(passfile);
126 Properties props = new EncryptedProperties();
127 try (FileInputStream fis = new FileInputStream(passfile)) {
139128 props.load(fis);
140129 String username = c.getUserName();
141130 String passwd = c.getPasswd();
148137 return new Credentials(c.getRealm(), c.getHost(), username, passwd);
149138 } catch (IOException e) {
150139 Message.warn("error occurred while loading password file " + passfile, e);
151 } finally {
152 if (fis != null) {
153 try {
154 fis.close();
155 } catch (IOException e) {
156 // ignored
157 }
158 }
159140 }
160141 }
161142 return c;
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.text.SimpleDateFormat;
2121 import java.util.Date;
2222
23 public class DateUtil {
23 public final class DateUtil {
2424
2525 private DateUtil() {
2626 // Utility class
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 private int level = Message.MSG_INFO;
2121
2222 /**
23 * @param level
23 * @param level ditto
2424 */
2525 public DefaultMessageLogger(int level) {
2626 this.level = level;
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17 package org.apache.ivy.util;
18
19 import java.util.Collection;
20 import java.util.LinkedList;
21 import java.util.List;
22 import java.util.Properties;
23
24 /**
25 * An implementation of Properties which stores the values encrypted. The use is transparent from
26 * the user point of view (use as any Properties instance), except that get, put and putAll do not
27 * handle encryption/decryption. This means that get returns the encrypted value, while put and
28 * putAll puts given values without encrypting them. It this thus recommended to void using them,
29 * use setProperty and getProperty instead.
30 */
31 @SuppressWarnings("serial")
32 public class EncryptedProperties extends Properties {
33
34 public EncryptedProperties() {
35 super();
36 }
37
38 public synchronized Object setProperty(String key, String value) {
39 return StringUtils.decrypt((String) super.setProperty(key, StringUtils.encrypt(value)));
40 }
41
42 public String getProperty(String key) {
43 return StringUtils.decrypt(super.getProperty(key));
44 }
45
46 public String getProperty(String key, String defaultValue) {
47 return StringUtils.decrypt(super.getProperty(key, StringUtils.encrypt(defaultValue)));
48 }
49
50 public boolean containsValue(Object value) {
51 return super.containsValue(StringUtils.encrypt((String) value));
52 }
53
54 public synchronized boolean contains(Object value) {
55 return super.contains(StringUtils.encrypt((String) value));
56 }
57
58 public Collection<Object> values() {
59 List<Object> ret = new LinkedList<>(super.values());
60 for (Object value : ret) {
61 ret.set(ret.indexOf(value), StringUtils.decrypt((String) value));
62 }
63 return ret;
64 }
65 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util;
1818
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.List;
22 import java.util.Properties;
23
2419 /**
25 * An implementation of Properties which stores the values encrypted. The use is transparent from
26 * the user point of view (use as any Properties instance), except that get, put and putAll do not
27 * handle encryption/decryption. This means that get returns the encrypted value, while put and
28 * putAll puts given values without encrypting them. It this thus recommended to void using them,
29 * use setProperty and getProperty instead.
20 * Deprecated because of renaming due spell check.
3021 */
31 public class EncrytedProperties extends Properties {
32
33 public EncrytedProperties() {
34 super();
35 }
36
37 public synchronized Object setProperty(String key, String value) {
38 return StringUtils.decrypt((String) super.setProperty(key, StringUtils.encrypt(value)));
39 }
40
41 public String getProperty(String key) {
42 return StringUtils.decrypt(super.getProperty(key));
43 }
44
45 public String getProperty(String key, String defaultValue) {
46 return StringUtils.decrypt(super.getProperty(key, StringUtils.encrypt(defaultValue)));
47 }
48
49 public boolean containsValue(Object value) {
50 return super.containsValue(StringUtils.encrypt((String) value));
51 }
52
53 public synchronized boolean contains(Object value) {
54 return super.contains(StringUtils.encrypt((String) value));
55 }
56
57 public Collection values() {
58 List ret = new ArrayList(super.values());
59 for (int i = 0; i < ret.size(); i++) {
60 ret.set(i, StringUtils.decrypt((String) ret.get(i)));
61 }
62 return ret;
63 }
22 @SuppressWarnings("serial")
23 @Deprecated
24 public class EncrytedProperties extends EncryptedProperties {
6425 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.File;
2020
2121 public interface FileResolver {
22 public static final FileResolver DEFAULT = new FileResolver() {
22 FileResolver DEFAULT = new FileResolver() {
2323 public File resolveFile(String path, String filename) {
2424 return new File(path);
2525 }
2929 * Return the canonical form of a path, or raise an {@link IllegalArgumentException} if the path
3030 * is not valid for this {@link FileResolver}.
3131 * <p>
32 *
32 *
3333 * @param path
3434 * The path of the file to resolve. Must not be <code>null</code>.
35 * @param fileName
35 * @param filename
3636 * The name of the file to resolve. This is used only for exception message if any.
3737 * Must not be <code>null</code>.
38 *
38 *
3939 * @return the resolved File.
40 *
40 *
4141 */
4242 File resolveFile(String path, String filename);
4343 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util;
1818
19 import org.apache.ivy.core.settings.TimeoutConstraint;
20 import org.apache.ivy.util.url.TimeoutConstrainedURLHandler;
21 import org.apache.ivy.util.url.URLHandler;
22 import org.apache.ivy.util.url.URLHandlerRegistry;
23
1924 import java.io.BufferedInputStream;
2025 import java.io.BufferedReader;
2126 import java.io.ByteArrayInputStream;
2530 import java.io.FileOutputStream;
2631 import java.io.IOException;
2732 import java.io.InputStream;
28 import java.io.InputStreamReader;
2933 import java.io.OutputStream;
3034 import java.net.URL;
35 import java.nio.file.Files;
36 import java.nio.file.NoSuchFileException;
3137 import java.util.ArrayList;
3238 import java.util.Arrays;
3339 import java.util.Collection;
3440 import java.util.Collections;
35 import java.util.Iterator;
3641 import java.util.List;
37 import java.util.Map;
38 import java.util.Map.Entry;
3942 import java.util.Stack;
4043 import java.util.StringTokenizer;
4144 import java.util.jar.JarOutputStream;
42 import java.util.jar.Pack200;
43 import java.util.jar.Pack200.Unpacker;
44 import java.util.regex.Pattern;
4545 import java.util.zip.GZIPInputStream;
4646 import java.util.zip.ZipInputStream;
4747
48 import org.apache.ivy.util.url.URLHandlerRegistry;
48 import static java.util.jar.Pack200.newUnpacker;
4949
5050 /**
5151 * Utility class used to deal with file related operations, like copy, full reading, symlink, ...
5656 // Utility class
5757 }
5858
59 // according to tests by users, 64kB seems to be a good value for the buffer used during copy
59 // according to tests by users, 64kB seems to be a good value for the buffer used during copy;
6060 // further improvements could be obtained using NIO API
6161 private static final int BUFFER_SIZE = 64 * 1024;
6262
6363 private static final byte[] EMPTY_BUFFER = new byte[0];
6464
65 private static final Pattern ALLOWED_PATH_PATTERN = Pattern.compile("[\\w-./\\\\:~ %\\(\\)]+");
66
67 public static void symlinkInMass(Map/* <File, File> */destToSrcMap, boolean overwrite)
65 /**
66 * Creates a symbolic link at {@code link} whose target will be the {@code target}. Depending
67 * on the underlying filesystem, this method may not always be able to create a symbolic link,
68 * in which case this method returns {@code false}.
69 *
70 * @param target The {@link File} which will be the target of the symlink being created
71 * @param link The path to the symlink that needs to be created
72 * @param overwrite {@code true} if any existing file at {@code link} has to be overwritten.
73 * False otherwise
74 * @return Returns true if the symlink was successfully created. Returns false if the symlink
75 * could not be created
76 * @throws IOException if {@link Files#createSymbolicLink} fails
77 */
78 public static boolean symlink(final File target, final File link, final boolean overwrite)
6879 throws IOException {
69
70 // This pattern could be more forgiving if somebody wanted it to be...
71 // ...but this should satisfy 99+% of all needs, without letting unsafe operations be done.
72 // If you paths is not supported, you then skip this mass option.
73 // NOTE: A space inside the path is allowed (I can't control other programmers who like them
74 // in their working directory names)...
75 // but trailing spaces on file names will be checked otherwise and refused.
76 try {
77 StringBuffer sb = new StringBuffer();
78
79 Iterator keyItr = destToSrcMap.entrySet().iterator();
80 while (keyItr.hasNext()) {
81 Entry/* <File, File> */entry = (Entry) keyItr.next();
82 File destFile = (File) entry.getKey();
83 File srcFile = (File) entry.getValue();
84 if (!ALLOWED_PATH_PATTERN.matcher(srcFile.getAbsolutePath()).matches()) {
85 throw new IOException("Unsafe file to 'mass' symlink: '"
86 + srcFile.getAbsolutePath() + "'");
87 }
88 if (!ALLOWED_PATH_PATTERN.matcher(destFile.getAbsolutePath()).matches()) {
89 throw new IOException("Unsafe file to 'mass' symlink to: '"
90 + destFile.getAbsolutePath() + "'");
91 }
92
93 // Add to our buffer of commands
94 sb.append("ln -s -f \"" + srcFile.getAbsolutePath() + "\" \""
95 + destFile.getAbsolutePath() + "\";");
96 if (keyItr.hasNext()) {
97 sb.append("\n");
98 }
99 }
100
101 String commands = sb.toString();
102 // Run the buffer of commands we have built.
103 Runtime runtime = Runtime.getRuntime();
104 Message.verbose("executing \"sh\" of:\n\t" + commands.replaceAll("\n", "\n\t"));
105 Process process = runtime.exec("sh");
106 OutputStream os = process.getOutputStream();
107 os.write(commands.getBytes("UTF-8"));
108 os.flush();
109 os.close();
110
111 if (process.waitFor() != 0) {
112 InputStream errorStream = process.getErrorStream();
113 InputStreamReader isr = new InputStreamReader(errorStream);
114 BufferedReader br = new BufferedReader(isr);
115
116 StringBuffer error = new StringBuffer();
117 String line;
118 while ((line = br.readLine()) != null) {
119 error.append(line);
120 error.append('\n');
121 }
122
123 throw new IOException("error running ln commands with 'sh':\n" + error);
124 }
125 } catch (InterruptedException x) {
126 Thread.currentThread().interrupt();
127 }
128 }
129
130 public static void symlink(File src, File dest, CopyProgressListener l, boolean overwrite)
131 throws IOException {
132 if (!prepareCopy(src, dest, overwrite)) {
133 return;
134 }
135 try {
136 Runtime runtime = Runtime.getRuntime();
137 Message.verbose("executing 'ln -s -f " + src.getAbsolutePath() + " " + dest.getPath()
138 + "'");
139 Process process = runtime.exec(new String[] {"ln", "-s", "-f", src.getAbsolutePath(),
140 dest.getPath()});
141
142 if (process.waitFor() != 0) {
143 InputStream errorStream = process.getErrorStream();
144 InputStreamReader isr = new InputStreamReader(errorStream);
145 BufferedReader br = new BufferedReader(isr);
146
147 StringBuffer error = new StringBuffer();
148 String line;
149 while ((line = br.readLine()) != null) {
150 error.append(line);
151 error.append('\n');
152 }
153
154 throw new IOException("error symlinking " + src + " to " + dest + ":\n" + error);
155 }
156
157 // check if the creation of the symbolic link was successful
158 if (!dest.exists()) {
159 throw new IOException("error symlinking: " + dest + " doesn't exists");
160 }
161
162 // check if the result is a true symbolic link
163 if (dest.getAbsolutePath().equals(dest.getCanonicalPath())) {
164 dest.delete(); // just make sure we do delete the invalid symlink!
165 throw new IOException("error symlinking: " + dest + " isn't a symlink");
166 }
167 } catch (IOException e) {
168 Message.verbose("symlink failed; falling back to copy", e);
169 copy(src, dest, l, overwrite);
170 } catch (InterruptedException x) {
171 Thread.currentThread().interrupt();
172 }
173 }
174
80 // prepare for symlink
81 if (target.isFile()) {
82 // it's a file that is being symlinked, so do the necessary preparation
83 // for the linking, similar to what we do with preparation for copying
84 if (!prepareCopy(target, link, overwrite)) {
85 return false;
86 }
87 } else {
88 // it's a directory being symlinked
89
90 // see if the directory represented by the "link" exists and is already a symbolic
91 // link. If it is and if we are asked to overwrite then we *only* break the link
92 // in preparation of symlink creation, later in this method
93 if (Files.isSymbolicLink(link.toPath()) && overwrite) {
94 Message.verbose("Un-linking existing symbolic link " + link + " during symlink creation, since overwrite=true");
95 Files.delete(link.toPath());
96 }
97 // make sure the "link" that is being created has the necessary parent directories
98 // in place before triggering symlink creation
99 if (link.getParentFile() != null) {
100 link.getParentFile().mkdirs();
101 }
102 }
103 Files.createSymbolicLink(link.toPath(), target.getAbsoluteFile().toPath());
104 return true;
105 }
106
107 /**
108 * This is the same as calling {@link #copy(File, File, CopyProgressListener, boolean)} with
109 * {@code overwrite} param as {@code true}
110 *
111 * @param src The source to copy
112 * @param dest The destination
113 * @param l A {@link CopyProgressListener}. Can be null
114 * @return Returns true if the file was copied. Else returns false
115 * @throws IOException If any exception occurs during the copy operation
116 */
175117 public static boolean copy(File src, File dest, CopyProgressListener l) throws IOException {
176118 return copy(src, dest, l, false);
177119 }
178120
179 public static boolean prepareCopy(File src, File dest, boolean overwrite) throws IOException {
121 public static boolean prepareCopy(final File src, final File dest, final boolean overwrite) throws IOException {
180122 if (src.isDirectory()) {
181123 if (dest.exists()) {
182124 if (!dest.isDirectory()) {
190132 }
191133 // else it is a file copy
192134 if (dest.exists()) {
135 // If overwrite is specified as "true" and the dest file happens to be a symlink,
136 // we delete the "link" (a.k.a unlink it). This is for cases like
137 // https://issues.apache.org/jira/browse/IVY-1498 where not unlinking the existing
138 // symlink can lead to potentially overwriting the wrong "target" file
139 // TODO: This behaviour is intentionally hardcoded here for now, since I don't
140 // see a reason (yet) to expose it as a param of this method. If any use case arises
141 // we can have this behaviour decided by the callers of this method, by passing
142 // a value for this param
143 final boolean unlinkSymlinkIfOverwrite = true;
193144 if (!dest.isFile()) {
194145 throw new IOException("impossible to copy: destination is not a file: " + dest);
195146 }
196147 if (overwrite) {
197 if (!dest.canWrite()) {
148 if (Files.isSymbolicLink(dest.toPath()) && unlinkSymlinkIfOverwrite) {
149 // unlink (a.k.a delete the symlink path)
150 dest.delete();
151 } else if (!dest.canWrite()) {
152 // if the file *isn't* "writable" (see javadoc of File.canWrite() on what
153 // that means) we delete it.
198154 dest.delete();
199155 } // if dest is writable, the copy will overwrite it without requiring a delete
200156 } else {
217173 return deepCopy(src, dest, l, overwrite);
218174 }
219175 // else it is a file copy
176 // check if it's the same file (the src and the dest). if they are the same, skip the copy
177 try {
178 if (Files.isSameFile(src.toPath(), dest.toPath())) {
179 Message.verbose("Skipping copy of file " + src + " to " + dest + " since they are the same file");
180 // we consider the file as copied if overwrite is true
181 return overwrite;
182 }
183 } catch (NoSuchFileException nsfe) {
184 // ignore and move on and attempt the copy
185 } catch (IOException ioe) {
186 // log and move on and attempt the copy
187 Message.verbose("Could not determine if " + src + " and dest " + dest + " are the same file", ioe);
188 }
220189 copy(new FileInputStream(src), dest, l);
221190 long srcLen = src.length();
222191 long destLen = dest.length();
233202 public static boolean deepCopy(File src, File dest, CopyProgressListener l, boolean overwrite)
234203 throws IOException {
235204 // the list of files which already exist in the destination folder
236 List/* <File> */existingChild = Collections.EMPTY_LIST;
205 List<File> existingChild = Collections.emptyList();
237206 if (dest.exists()) {
238207 if (!dest.isDirectory()) {
239208 // not expected type, remove
245214 // existing folder, gather existing children
246215 File[] children = dest.listFiles();
247216 if (children != null) {
248 existingChild = Arrays.asList(children);
217 existingChild = new ArrayList<>(Arrays.asList(children));
249218 }
250219 }
251220 } else {
255224 // copy files one by one
256225 File[] toCopy = src.listFiles();
257226 if (toCopy != null) {
258 for (int i = 0; i < toCopy.length; i++) {
227 for (File cf : toCopy) {
259228 // compute the destination file
260 File childDest = new File(dest, toCopy[i].getName());
229 File childDest = new File(dest, cf.getName());
261230 // if file existing, 'mark' it as taken care of
262 existingChild.remove(childDest);
263 if (toCopy[i].isDirectory()) {
264 deepCopy(toCopy[i], childDest, l, overwrite);
231 if (!existingChild.isEmpty()) {
232 existingChild.remove(childDest);
233 }
234 if (cf.isDirectory()) {
235 deepCopy(cf, childDest, l, overwrite);
265236 } else {
266 copy(toCopy[i], childDest, l, overwrite);
237 copy(cf, childDest, l, overwrite);
267238 }
268239 }
269240 }
270241 // some file exist in the destination but not in the source: delete them
271 for (int i = 0; i < existingChild.size(); i++) {
272 forceDelete((File) existingChild.get(i));
242 for (File child : existingChild) {
243 forceDelete(child);
273244 }
274245 return true;
275246 }
276247
277 public static void copy(URL src, File dest, CopyProgressListener l) throws IOException {
278 URLHandlerRegistry.getDefault().download(src, dest, l);
279 }
280
281 public static void copy(File src, URL dest, CopyProgressListener l) throws IOException {
282 URLHandlerRegistry.getDefault().upload(src, dest, l);
248 @SuppressWarnings("deprecation")
249 public static void copy(final URL src, final File dest, final CopyProgressListener listener,
250 final TimeoutConstraint timeoutConstraint) throws IOException {
251 final URLHandler handler = URLHandlerRegistry.getDefault();
252 if (handler instanceof TimeoutConstrainedURLHandler) {
253 ((TimeoutConstrainedURLHandler) handler).download(src, dest, listener, timeoutConstraint);
254 return;
255 }
256 handler.download(src, dest, listener);
257 }
258
259 @SuppressWarnings("deprecation")
260 public static void copy(final File src, final URL dest, final CopyProgressListener listener,
261 final TimeoutConstraint timeoutConstraint) throws IOException {
262 final URLHandler handler = URLHandlerRegistry.getDefault();
263 if (handler instanceof TimeoutConstrainedURLHandler) {
264 ((TimeoutConstrainedURLHandler) handler).upload(src, dest, listener, timeoutConstraint);
265 return;
266 }
267 handler.upload(src, dest, listener);
283268 }
284269
285270 public static void copy(InputStream src, File dest, CopyProgressListener l) throws IOException {
363348 * <p>
364349 * The BufferedReader is closed when this method returns.
365350 * </p>
366 *
351 *
367352 * @param in
368353 * the {@link BufferedReader} to read from
369354 * @return a String with the whole content read from the {@link BufferedReader}
372357 */
373358 public static String readEntirely(BufferedReader in) throws IOException {
374359 try {
375 StringBuffer buf = new StringBuffer();
360 StringBuilder buf = new StringBuilder();
376361
377362 String line = in.readLine();
378363 while (line != null) {
379 buf.append(line + "\n");
364 buf.append(line).append("\n");
380365 line = in.readLine();
381366 }
382367 return buf.toString();
387372
388373 /**
389374 * Reads the entire content of the file and returns it as a String.
390 *
375 *
391376 * @param f
392377 * the file to read from
393378 * @return a String with the file content
403388 * <p>
404389 * The input stream is closed when this method returns.
405390 * </p>
406 *
391 *
407392 * @param is
408393 * the {@link InputStream} to read from
409394 * @return a String with the input stream content
412397 */
413398 public static String readEntirely(InputStream is) throws IOException {
414399 try {
415 StringBuffer sb = new StringBuffer();
400 StringBuilder sb = new StringBuilder();
416401 byte[] buffer = new byte[BUFFER_SIZE];
417402 int c;
418403
431416
432417 /**
433418 * Recursively delete file
434 *
419 *
435420 * @param file
436421 * the file to delete
437422 * @return true if the deletion completed successfully (ie if the file does not exist on the
444429 if (file.isDirectory()) {
445430 File[] files = file.listFiles();
446431 if (files != null) {
447 for (int i = 0; i < files.length; i++) {
448 if (!forceDelete(files[i])) {
432 for (File df : files) {
433 if (!forceDelete(df)) {
449434 return false;
450435 }
451436 }
456441
457442 /**
458443 * Returns a list of Files composed of all directories being parent of file and child of root +
459 * file and root themselves. Example: getPathFiles(new File("test"), new
460 * File("test/dir1/dir2/file.txt")) => {new File("test/dir1"), new File("test/dir1/dir2"), new
461 * File("test/dir1/dir2/file.txt") } Note that if root is not an ancester of file, or if root is
462 * null, all directories from the file system root will be returned.
463 */
464 public static List getPathFiles(File root, File file) {
465 List ret = new ArrayList();
444 * file and root themselves. Example: <code>getPathFiles(new File("test"), new
445 * File("test/dir1/dir2/file.txt")) =&gt; {new File("test/dir1"), new File("test/dir1/dir2"),
446 * new File("test/dir1/dir2/file.txt") }</code> Note that if root is not an ancestor of file, or
447 * if root is null, all directories from the file system root will be returned.
448 *
449 * @param root File
450 * @param file File
451 * @return List&lt;File&gt;
452 */
453 public static List<File> getPathFiles(File root, File file) {
454 List<File> ret = new ArrayList<>();
466455 while (file != null && !file.getAbsolutePath().equals(root.getAbsolutePath())) {
467456 ret.add(file);
468457 file = file.getParentFile();
475464 }
476465
477466 /**
478 * Returns a collection of all Files being contained in the given directory, recursively,
479 * including directories.
480 *
481467 * @param dir
482468 * The directory from which all files, including files in subdirectory) are
483469 * extracted.
484470 * @param ignore
485471 * a Collection of filenames which must be excluded from listing
486 * @return A collectoin containing all the files of the given directory and it's subdirectories.
487 */
488 public static Collection listAll(File dir, Collection ignore) {
489 return listAll(dir, new ArrayList(), ignore);
490 }
491
492 private static Collection listAll(File file, Collection list, Collection ignore) {
472 * @return a collection containing all the files of the given directory and it's subdirectories,
473 * recursively.
474 */
475 public static Collection<File> listAll(File dir, Collection<String> ignore) {
476 return listAll(dir, new ArrayList<File>(), ignore);
477 }
478
479 private static Collection<File> listAll(File file, Collection<File> list,
480 Collection<String> ignore) {
493481 if (ignore.contains(file.getName())) {
494482 return list;
495483 }
499487 }
500488 if (file.isDirectory()) {
501489 File[] files = file.listFiles();
502 for (int i = 0; i < files.length; i++) {
503 listAll(files[i], list, ignore);
490 for (File lf : files) {
491 listAll(lf, list, ignore);
504492 }
505493 }
506494 return list;
521509
522510 /**
523511 * &quot;Normalize&quot; the given absolute path.
524 *
512 *
525513 * <p>
526514 * This includes:
527515 * <ul>
532520 * </ul>
533521 * Unlike {@link File#getCanonicalPath()} this method specifically does not resolve symbolic
534522 * links.
535 *
536 * @param path
537 * the path to be normalized.
523 *
524 * @param path the path to be normalized.
538525 * @return the normalized version of the path.
539 *
540 * @throws java.lang.NullPointerException
541 * if path is null.
526 * @throws NullPointerException if path is null.
542527 */
543528 public static File normalize(final String path) {
544 Stack s = new Stack();
545 String[] dissect = dissect(path);
546 s.push(dissect[0]);
547
548 StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
529 final Stack<String> s = new Stack<>();
530 final DissectedPath dissectedPath = dissect(path);
531 s.push(dissectedPath.root);
532
533 final StringTokenizer tok = new StringTokenizer(dissectedPath.remainingPath, File.separator);
549534 while (tok.hasMoreTokens()) {
550535 String thisToken = tok.nextToken();
551536 if (".".equals(thisToken)) {
561546 s.push(thisToken);
562547 }
563548 }
564 StringBuffer sb = new StringBuffer();
549 StringBuilder sb = new StringBuilder();
565550 for (int i = 0; i < s.size(); i++) {
566551 if (i > 1) {
567552 // not before the filesystem root and not after it, since root
575560
576561 /**
577562 * Dissect the specified absolute path.
578 *
563 *
579564 * @param path
580565 * the path to dissect.
581 * @return String[] {root, remaining path}.
566 * @return {@link DissectedPath}
582567 * @throws java.lang.NullPointerException
583568 * if path is null.
584569 * @since Ant 1.7
585570 */
586 private static String[] dissect(String path) {
587 char sep = File.separatorChar;
588 path = path.replace('/', sep).replace('\\', sep);
589
590 // // make sure we are dealing with an absolute path
591 // if (!isAbsolutePath(path)) {
592 // throw new BuildException(path + " is not an absolute path");
593 // }
594 String root = null;
595 int colon = path.indexOf(':');
596 if (colon > 0) { // && (ON_DOS || ON_NETWARE)) {
597
598 int next = colon + 1;
599 root = path.substring(0, next);
600 char[] ca = path.toCharArray();
601 root += sep;
602 // remove the initial separator; the root has it.
603 next = (ca[next] == sep) ? next + 1 : next;
604
605 StringBuffer sbPath = new StringBuffer();
606 // Eliminate consecutive slashes after the drive spec:
607 for (int i = next; i < ca.length; i++) {
608 if (ca[i] != sep || ca[i - 1] != sep) {
609 sbPath.append(ca[i]);
610 }
611 }
612 path = sbPath.toString();
613 } else if (path.length() > 1 && path.charAt(1) == sep) {
614 // UNC drive
615 int nextsep = path.indexOf(sep, 2);
616 nextsep = path.indexOf(sep, nextsep + 1);
617 root = (nextsep > 2) ? path.substring(0, nextsep + 1) : path;
618 path = path.substring(root.length());
619 } else {
620 root = File.separator;
621 path = path.substring(1);
622 }
623 return new String[] {root, path};
571 private static DissectedPath dissect(final String path) {
572 final char sep = File.separatorChar;
573 final String pathToDissect = path.replace('/', sep).replace('\\', sep).trim();
574
575 // check if the path starts with a filesystem root
576 final File[] filesystemRoots = File.listRoots();
577 if (filesystemRoots != null) {
578 for (final File filesystemRoot : filesystemRoots) {
579 if (pathToDissect.startsWith(filesystemRoot.getPath())) {
580 // filesystem root is the root and the rest of the path is the "remaining path"
581 final String root = filesystemRoot.getPath();
582 final String rest = pathToDissect.substring(root.length());
583 final StringBuilder sbPath = new StringBuilder();
584 // Eliminate consecutive slashes after the drive spec:
585 for (int i = 0; i < rest.length(); i++) {
586 final char currentChar = rest.charAt(i);
587 if (i == 0) {
588 sbPath.append(currentChar);
589 continue;
590 }
591 final char previousChar = rest.charAt(i - 1);
592 if (currentChar != sep || previousChar != sep) {
593 sbPath.append(currentChar);
594 }
595 }
596 return new DissectedPath(root, sbPath.toString());
597 }
598 }
599 }
600 // UNC drive
601 if (pathToDissect.length() > 1 && pathToDissect.charAt(1) == sep) {
602 int nextsep = pathToDissect.indexOf(sep, 2);
603 nextsep = pathToDissect.indexOf(sep, nextsep + 1);
604 final String root = (nextsep > 2) ? pathToDissect.substring(0, nextsep + 1) : pathToDissect;
605 final String rest = pathToDissect.substring(root.length());
606 return new DissectedPath(root, rest);
607 }
608
609 return new DissectedPath(File.separator, pathToDissect);
624610 }
625611
626612 /**
627613 * Get the length of the file, or the sum of the children lengths if it is a directory
628 *
629 * @param file
630 * @return
614 *
615 * @param file File
616 * @return long
631617 */
632618 public static long getFileLength(File file) {
633619 long l = 0;
634620 if (file.isDirectory()) {
635621 File[] files = file.listFiles();
636622 if (files != null) {
637 for (int i = 0; i < files.length; i++) {
638 l += getFileLength(files[i]);
623 for (File gf : files) {
624 l += getFileLength(gf);
639625 }
640626 }
641627 } else {
658644 in = new GZIPInputStream(in);
659645 }
660646
661 Unpacker unpacker = Pack200.newUnpacker();
662647 ByteArrayOutputStream baos = new ByteArrayOutputStream();
663648 JarOutputStream jar = new JarOutputStream(baos);
664 unpacker.unpack(new UncloseInputStream(in), jar);
649 newUnpacker().unpack(new UncloseInputStream(in), jar);
665650 jar.close();
666651 return new ByteArrayInputStream(baos.toByteArray());
667652 }
668653
669654 /**
670655 * Wrap an input stream and do not close the stream on call to close(). Used to avoid closing a
671 * {@link ZipInputStream} used with {@link Unpacker#unpack(File, JarOutputStream)}
656 * {@link ZipInputStream} used with {@link Pack200.Unpacker#unpack(File, JarOutputStream)}
672657 */
673658 private static final class UncloseInputStream extends InputStream {
674659
678663 this.wrapped = wrapped;
679664 }
680665
666 @Override
681667 public void close() throws IOException {
682668 // do not close
683669 }
684670
671 @Override
685672 public int read() throws IOException {
686673 return wrapped.read();
687674 }
688675
676 @Override
689677 public int hashCode() {
690678 return wrapped.hashCode();
691679 }
692680
681 @Override
693682 public int read(byte[] b) throws IOException {
694683 return wrapped.read(b);
695684 }
696685
686 @Override
697687 public boolean equals(Object obj) {
698688 return wrapped.equals(obj);
699689 }
700690
691 @Override
701692 public int read(byte[] b, int off, int len) throws IOException {
702693 return wrapped.read(b, off, len);
703694 }
704695
696 @Override
705697 public long skip(long n) throws IOException {
706698 return wrapped.skip(n);
707699 }
708700
701 @Override
709702 public String toString() {
710703 return wrapped.toString();
711704 }
712705
706 @Override
713707 public int available() throws IOException {
714708 return wrapped.available();
715709 }
716710
711 @Override
717712 public void mark(int readlimit) {
718713 wrapped.mark(readlimit);
719714 }
720715
716 @Override
721717 public void reset() throws IOException {
722718 wrapped.reset();
723719 }
724720
721 @Override
725722 public boolean markSupported() {
726723 return wrapped.markSupported();
727724 }
728725
729726 }
727
728 private static final class DissectedPath {
729 private final String root;
730
731 private final String remainingPath;
732
733 private DissectedPath(final String root, final String remainingPath) {
734 this.root = root;
735 this.remainingPath = remainingPath;
736 }
737
738 @Override
739 public String toString() {
740 return "Dissected Path [root=" + root + ", remainingPath="
741 + remainingPath + "]";
742 }
743 }
730744 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 'b', 'c', 'd', 'e', 'f'};
2626
2727 public static String encode(byte[] packet) {
28 StringBuffer chars = new StringBuffer(16);
29 for (int i = 0; i < packet.length; i++) {
30 int highBits = (packet[i] & 0xF0) >> 4;
31 int lowBits = packet[i] & 0x0F;
32 chars.append(ALPHABET[highBits]);
33 chars.append(ALPHABET[lowBits]);
28 StringBuilder chars = new StringBuilder(16);
29 for (byte bt : packet) {
30 int highBits = (bt & 0xF0) >> 4;
31 int lowBits = bt & 0x0F;
32 chars.append(ALPHABET[highBits]).append(ALPHABET[lowBits]);
3433 }
3534 return chars.toString();
3635 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 /**
2323 * This class contains basic helper methods for the Host.
24 *
24 *
2525 */
2626 public final class HostUtil {
2727
3636 /**
3737 * This method returns the name of the current Host, if this name cannot be determined,
3838 * localhost will be returned.
39 *
39 *
4040 * @return The name of the current "local" Host.
4141 */
4242 public static String getLocalHostName() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929
3030 /**
3131 * Returns the approximate size of a default instance of the given class.
32 *
32 *
3333 * @param clazz
3434 * the class to evaluate.
3535 * @return the estimated size of instance, in bytes.
3636 */
37 public static long sizeOf(Class clazz) {
37 public static long sizeOf(Class<?> clazz) {
3838 long size = 0;
3939 Object[] objects = new Object[SAMPLING_SIZE];
4040 try {
5656 * Returns the currently used memory, after calling garbage collector and waiting enough to get
5757 * maximal chance it is actually called. But since {@link Runtime#gc()} is only advisory,
5858 * results returned by this method should be treated as rough approximation only.
59 *
59 *
6060 * @return the currently used memory, in bytes.
6161 */
6262 public static long getUsedMemory() {
6464 long totalMemory = Runtime.getRuntime().totalMemory();
6565 gc();
6666 long freeMemory = Runtime.getRuntime().freeMemory();
67 long usedMemory = totalMemory - freeMemory;
68 return usedMemory;
67 return totalMemory - freeMemory;
6968 }
7069
7170 private static void gc() {
8685 public static void main(String[] args) throws ClassNotFoundException {
8786 System.out.println(sizeOf(Class.forName(args[0])));
8887 }
89 }
88 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
5454
5555 /**
5656 * Returns the current default logger.
57 *
57 *
5858 * @return the current default logger; is never <code>null</code>.
5959 */
6060 public static MessageLogger getDefaultLogger() {
6363
6464 /**
6565 * Change the default logger used when no other logger is currently configured
66 *
66 *
6767 * @param logger
6868 * the new default logger, must not be <code>null</code>
6969 */
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
3131 * message at a lower level (usually {@link Message#MSG_VERBOSE}) and log the message at the actual
3232 * level only when {@link #sumupProblems()} is called.
3333 * </p>
34 *
34 *
3535 * @see Message
3636 */
3737 public interface MessageLogger {
4040 * <p>
4141 * <code>level</code> constants are defined in the {@link Message} class.
4242 * </p>
43 *
43 *
4444 * @param msg
4545 * the message to log
4646 * @param level
4949 * @see Message#MSG_VERBOSE
5050 * @see Message#MSG_INFO
5151 * @see Message#MSG_WARN
52 * @see Message#MSG_ERROR
52 * @see Message#MSG_ERR
5353 */
54 public abstract void log(String msg, int level);
54 void log(String msg, int level);
5555
5656 /**
5757 * Same as {@link #log(String, int)}, but without adding any contextual information to the
5858 * message.
59 *
59 *
6060 * @param msg
6161 * the message to log
6262 * @param level
6363 * the level at which the message should be logged.
6464 */
65 public abstract void rawlog(String msg, int level);
65 void rawlog(String msg, int level);
6666
67 public abstract void debug(String msg);
67 void debug(String msg);
6868
69 public abstract void verbose(String msg);
69 void verbose(String msg);
7070
71 public abstract void deprecated(String msg);
71 void deprecated(String msg);
7272
73 public abstract void info(String msg);
73 void info(String msg);
7474
75 public abstract void rawinfo(String msg);
75 void rawinfo(String msg);
7676
77 public abstract void warn(String msg);
77 void warn(String msg);
7878
79 public abstract void error(String msg);
79 void error(String msg);
8080
81 public abstract List<String> getProblems();
81 List<String> getProblems();
8282
83 public abstract List<String> getWarns();
83 List<String> getWarns();
8484
85 public abstract List<String> getErrors();
85 List<String> getErrors();
8686
8787 /**
8888 * Clears the list of problems, warns and errors.
8989 */
90 public abstract void clearProblems();
90 void clearProblems();
9191
9292 /**
9393 * Sumup all problems encountered so far, and clear them.
9494 */
95 public abstract void sumupProblems();
95 void sumupProblems();
9696
97 public abstract void progress();
97 void progress();
9898
99 public abstract void endProgress();
99 void endProgress();
100100
101 public abstract void endProgress(String msg);
101 void endProgress(String msg);
102102
103 public abstract boolean isShowProgress();
103 boolean isShowProgress();
104104
105 public abstract void setShowProgress(boolean progress);
105 void setShowProgress(boolean progress);
106106
107 }
107 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.util;
1818
1919 import java.util.ArrayList;
20 import java.util.Iterator;
2120 import java.util.List;
2221 import java.util.Stack;
2322
3332 * </p>
3433 */
3534 public class MessageLoggerEngine implements MessageLogger {
36 private final ThreadLocal/* <Stack<MessageLogger>> */loggerStacks = new ThreadLocal();
35 private final ThreadLocal<Stack<MessageLogger>> loggerStacks = new ThreadLocal<>();
3736
3837 private MessageLogger defaultLogger = null;
3938
40 private List problems = new ArrayList();
41
42 private List warns = new ArrayList();
43
44 private List errors = new ArrayList();
45
46 private Stack getLoggerStack() {
47 Stack stack = (Stack) loggerStacks.get();
39 private List<String> problems = new ArrayList<>();
40
41 private List<String> warns = new ArrayList<>();
42
43 private List<String> errors = new ArrayList<>();
44
45 private Stack<MessageLogger> getLoggerStack() {
46 Stack<MessageLogger> stack = loggerStacks.get();
4847 if (stack == null) {
49 stack = new Stack();
48 stack = new Stack<>();
5049 loggerStacks.set(stack);
5150 }
5251 return stack;
5756
5857 /**
5958 * Sets the logger used when the stack is empty.
60 *
59 *
6160 * @param defaultLogger
6261 * the logger to use when the stack is empty.
6362 */
6766
6867 /**
6968 * Push a logger on the stack.
70 *
69 *
7170 * @param logger
7271 * the logger to push. Must not be <code>null</code>.
7372 */
9089
9190 /**
9291 * Returns the current logger, or the default one if there is no logger in the stack
93 *
92 *
9493 * @return the current logger, or the default one if there is no logger in the stack
9594 */
9695 public MessageLogger peekLogger() {
9796 if (getLoggerStack().isEmpty()) {
9897 return getDefaultLogger();
9998 }
100 return (MessageLogger) getLoggerStack().peek();
99 return getLoggerStack().peek();
101100 }
102101
103102 private MessageLogger getDefaultLogger() {
119118 errors.add(msg);
120119 }
121120
122 public List getErrors() {
121 public List<String> getErrors() {
123122 return errors;
124123 }
125124
126 public List getProblems() {
125 public List<String> getProblems() {
127126 return problems;
128127 }
129128
130 public List getWarns() {
129 public List<String> getWarns() {
131130 return warns;
132131 }
133132
138137
139138 public void clearProblems() {
140139 getDefaultLogger().clearProblems();
141 for (Iterator iter = getLoggerStack().iterator(); iter.hasNext();) {
142 MessageLogger l = (MessageLogger) iter.next();
140 for (MessageLogger l : getLoggerStack()) {
143141 l.clearProblems();
144142 }
145143 problems.clear();
150148 public void setShowProgress(boolean progress) {
151149 getDefaultLogger().setShowProgress(progress);
152150 // updates all loggers in the stack
153 for (Iterator iter = getLoggerStack().iterator(); iter.hasNext();) {
154 MessageLogger l = (MessageLogger) iter.next();
151 for (MessageLogger l : getLoggerStack()) {
155152 l.setShowProgress(progress);
156153 }
157154 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util;
1818
19 import java.util.Iterator;
2019 import java.util.List;
2120
2221 public final class MessageLoggerHelper {
2322 public static void sumupProblems(MessageLogger logger) {
24 List myProblems = logger.getProblems();
23 List<String> myProblems = logger.getProblems();
2524 if (myProblems.size() > 0) {
26 List myWarns = logger.getWarns();
27 List myErrors = logger.getErrors();
25 List<String> myWarns = logger.getWarns();
26 List<String> myErrors = logger.getErrors();
2827 logger.info(""); // new line on info to isolate error summary
2928 if (!myErrors.isEmpty()) {
3029 logger.log(":: problems summary ::", Message.MSG_ERR);
3332 }
3433 if (myWarns.size() > 0) {
3534 logger.log(":::: WARNINGS", Message.MSG_WARN);
36 for (Iterator iter = myWarns.iterator(); iter.hasNext();) {
37 String msg = (String) iter.next();
35 for (String msg : myWarns) {
3836 logger.log("\t" + msg + "\n", Message.MSG_WARN);
3937 }
4038 }
4139 if (myErrors.size() > 0) {
4240 logger.log(":::: ERRORS", Message.MSG_ERR);
43 for (Iterator iter = myErrors.iterator(); iter.hasNext();) {
44 String msg = (String) iter.next();
41 for (String msg : myErrors) {
4542 logger.log("\t" + msg + "\n", Message.MSG_ERR);
4643 }
4744 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 /**
2626 * A simple Properties extension easing the loading and saving of data
2727 */
28 @SuppressWarnings("serial")
2829 public class PropertiesFile extends Properties {
2930 private File file;
3031
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 import java.util.Locale;
2323
2424 /**
25 * Convenient class used only for uncapitalization Usually use commons lang but here we do not want
25 * Convenient class used only for uncapitalization. Usually use commons lang but here we do not want
2626 * to have such a dependency for only one feature
2727 */
2828 public final class StringUtils {
3232 }
3333
3434 public static String uncapitalize(String string) {
35 if (string == null || string.length() == 0) {
35 if (isNullOrEmpty(string)) {
3636 return string;
3737 }
3838 if (string.length() == 1) {
4545 * Returns the error message associated with the given Throwable. The error message returned
4646 * will try to be as precise as possible, handling cases where e.getMessage() is not meaningful,
4747 * like {@link NullPointerException} for instance.
48 *
49 * @param t
50 * the throwable to get the error message from
48 *
49 * @param t the throwable to get the error message from
5150 * @return the error message of the given exception
5251 */
5352 public static String getErrorMessage(Throwable t) {
5857 InvocationTargetException ex = (InvocationTargetException) t;
5958 t = ex.getTargetException();
6059 }
61 String errMsg = t instanceof RuntimeException ? t.getMessage() : t.toString();
62 if (errMsg == null || errMsg.length() == 0 || "null".equals(errMsg)) {
60 String errMsg = (t instanceof RuntimeException) ? t.getMessage() : t.toString();
61 if (isNullOrEmpty(errMsg) || "null".equals(errMsg)) {
6362 errMsg = t.getClass().getName() + " at " + t.getStackTrace()[0].toString();
6463 }
6564 return errMsg;
6766
6867 /**
6968 * Returns the exception stack trace as a String.
70 *
69 *
7170 * @param e
7271 * the exception to get the stack trace from.
7372 * @return the exception stack trace
8281 return sw.getBuffer().toString();
8382 }
8483
85 /**
86 * Joins the given object array in one string, each separated by the given separator.
87 *
84 @Deprecated
85 public static String join(Object[] objs, String sep) {
86 for (int i = 0; i < objs.length; i++) {
87 if (!(objs[i] instanceof String)) {
88 objs[i] = objs[i].toString();
89 }
90 }
91 return joinArray((String[]) objs, sep);
92 }
93
94 /**
95 * Joins the given string array in one string, each separated by the given separator.
96 *
8897 * Example:
89 *
98 *
9099 * <pre>
91 * join(new String[] {"one", "two", "three"}, ", ") -> "one, two, three"
100 * joinArray(new String[] {"one", "two", "three"}, ", ") -&gt; "one, two, three"
92101 * </pre>
93 *
102 *
94103 * @param objs
95 * The array of objects (<code>toString()</code> is used).
104 * The array of strings.
96105 * @param sep
97106 * The separator to use.
98 * @return The concatinated string.
99 */
100 public static String join(Object[] objs, String sep) {
101 StringBuffer buf = new StringBuffer();
102 for (int i = 0; i < objs.length; i++) {
103 buf.append(objs[i]).append(sep);
107 * @return The concatenated string.
108 */
109 public static String joinArray(String[] objs, String sep) {
110 StringBuilder buf = new StringBuilder();
111 for (String obj : objs) {
112 buf.append(obj).append(sep);
104113 }
105114 if (objs.length > 0) {
106115 buf.setLength(buf.length() - sep.length()); // delete sep
108117 return buf.toString();
109118 }
110119
120 /**
121 * Splits the given string into a string array using comma as a separator.
122 * Every array member gets {@link String#trim() trimmed}.
123 *
124 * @param list the string
125 * @return String[]
126 */
127 public static String[] splitToArray(String list) {
128 if (list == null) {
129 return null;
130 }
131 return list.trim().split("\\s*,\\s*");
132 }
133
134 /**
135 * Checks that a string is not null or consists of whitespace by {@link String#trim() trimming}
136 * and checking the {@link String#isEmpty() length} of the result.
137 *
138 * @param s the string to check
139 * @return boolean
140 */
141 public static boolean isNullOrEmpty(String s) {
142 return s == null || s.trim().isEmpty();
143 }
144
145 /**
146 * Asserts that the passed <code>value</code> is not null and not an empty {@link String}.
147 * The implementation of this method {@link String#trim() trims} the (non-null)
148 * <code>value</code> to check whether the value is an empty string. If the <code>value</code>
149 * is either null or empty, then this method throws an {@link IllegalArgumentException}
150 * with the passed <code>errorMessage</code> as the message in the exception.
151 *
152 * @param value The value to check for
153 * @param errorMessage The error message
154 */
155 public static void assertNotNullNorEmpty(final String value, final String errorMessage) {
156 if (isNullOrEmpty(value)) {
157 throw new IllegalArgumentException(errorMessage);
158 }
159 }
160
161 @Deprecated
162 public static void assertNotNullNotEmpty(final String value, final String errorMessage) {
163 assertNotNullNorEmpty(value, errorMessage);
164 }
165
111166 // basic string codec (same algo as CVS passfile, inspired by ant CVSPass class
112 /** Array contain char conversion data */
167 /**
168 * Array containing char conversion data
169 */
113170 private static final char[] SHIFTS = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
114171 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 114, 120, 53, 79, 96, 109,
115172 72, 108, 70, 64, 76, 67, 116, 74, 68, 87, 111, 52, 75, 119, 49, 34, 82, 81, 95, 65,
129186 * Encrypt the given string in a way which anybody having access to this method algorithm can
130187 * easily decrypt. This is useful only to avoid clear string storage in a file for example, but
131188 * shouldn't be considered as a real mean of security. This only works with simple characters
132 * (char < 256).
133 *
189 * (char &lt; 256).
190 *
134191 * @param str
135192 * the string to encrypt
136193 * @return the encrypted version of the string
139196 if (str == null) {
140197 return null;
141198 }
142 StringBuffer buf = new StringBuffer();
143 for (int i = 0; i < str.length(); i++) {
144 char c = str.charAt(i);
199 StringBuilder buf = new StringBuilder();
200 for (char c : str.toCharArray()) {
145201 if (c >= SHIFTS.length) {
146202 throw new IllegalArgumentException(
147203 "encrypt method can only be used with simple characters. '" + c
154210
155211 /**
156212 * Decrypts a string encrypted with encrypt.
157 *
213 *
158214 * @param str
159215 * the encrypted string to decrypt
160216 * @return The decrypted string.
163219 if (str == null) {
164220 return null;
165221 }
166 StringBuffer buf = new StringBuffer();
167 for (int i = 0; i < str.length(); i++) {
168 buf.append(decrypt(str.charAt(i)));
222 StringBuilder buf = new StringBuilder();
223 for (char c : str.toCharArray()) {
224 buf.append(decrypt(c));
169225 }
170226 return buf.toString();
171227 }
181237 }
182238
183239 public static String repeat(String str, int count) {
184 StringBuffer sb = new StringBuffer();
240 StringBuilder sb = new StringBuilder();
185241 for (int i = 0; i < count; i++) {
186242 sb.append(str);
187243 }
188244 return sb.toString();
189245 }
190
191246 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
6363 }
6464 SAXParser parser = parserFactory.newSAXParser();
6565
66 if (canUseSchemaValidation && (schema != null)) {
66 if (canUseSchemaValidation && schema != null) {
6767 try {
6868 parser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
6969 parser.setProperty(JAXP_SCHEMA_SOURCE, schemaStream);
8989 canDisableExternalDtds = Boolean.FALSE;
9090 }
9191 }
92 return canDisableExternalDtds.booleanValue();
92 return canDisableExternalDtds;
9393 }
9494
9595 /**
9696 * Convert an URL to a valid systemId according to RFC 2396.
97 *
98 * @param url URL
99 * @return String
97100 */
98101 public static String toSystemId(URL url) {
99102 try {
104107 }
105108
106109 // IMPORTANT: validation errors are only notified to the given handler, and
107 // do not cause exception
108 // implement warning error and fatalError methods in handler to be informed
109 // of validation errors
110 // do not cause exception implement warning error and fatalError methods in
111 // handler to be informed of validation errors
112
110113 public static void parse(URL xmlURL, URL schema, DefaultHandler handler) throws SAXException,
111114 IOException, ParserConfigurationException {
112115 parse(xmlURL, schema, handler, null);
113116 }
114117
118 @SuppressWarnings("deprecation")
115119 public static void parse(URL xmlURL, URL schema, DefaultHandler handler, LexicalHandler lHandler)
116120 throws SAXException, IOException, ParserConfigurationException {
117 InputStream xmlStream = URLHandlerRegistry.getDefault().openStream(xmlURL);
118 try {
121 try (InputStream xmlStream = URLHandlerRegistry.getDefault().openStream(xmlURL)) {
119122 InputSource inSrc = new InputSource(xmlStream);
120123 inSrc.setSystemId(toSystemId(xmlURL));
121124 parse(inSrc, schema, handler, lHandler);
122 } finally {
123 try {
124 xmlStream.close();
125 } catch (IOException e) {
126 // ignored
127 }
128125 }
129126 }
130127
138135 parse(xmlStream, schema, handler, lHandler, true);
139136 }
140137
138 @SuppressWarnings("deprecation")
141139 public static void parse(InputSource xmlStream, URL schema, DefaultHandler handler,
142140 LexicalHandler lHandler, boolean loadExternalDtds) throws SAXException, IOException,
143141 ParserConfigurationException {
176174
177175 /**
178176 * Escapes invalid XML characters in the given character data using XML entities. For the
179 * moment, only the following characters are being escaped: (<), (&), (') and (").
180 *
181 * Remark: we don't escape the (>) character to keep the readability of the configuration
182 * mapping! The XML spec only requires that the (&) and (<) characters are being escaped inside
183 * character data.
184 *
177 * moment, only the following characters are being escaped: (&lt;), (&amp;), (') and (&quot;).
178 *
179 * Remark: we don't escape the (&gt;) character to keep the readability of the configuration
180 * mapping! The XML spec only requires that the (&amp;) and (&lt;) characters are being escaped
181 * inside character data.
182 *
185183 * @param text
186184 * the character data to escape
187185 * @return the escaped character data
191189 return null;
192190 }
193191
194 StringBuffer result = new StringBuffer(text.length());
195
196 char[] chars = text.toCharArray();
197 for (int i = 0; i < chars.length; i++) {
198 switch (chars[i]) {
192 StringBuilder result = new StringBuilder(text.length());
193
194 for (char ch : text.toCharArray()) {
195 switch (ch) {
199196 case '&':
200197 result.append("&amp;");
201198 break;
209206 result.append("&quot;");
210207 break;
211208 default:
212 result.append(chars[i]);
209 result.append(ch);
213210 }
214211 }
215212
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.util.Map;
2121
2222 public class CommandLine {
23 private Map/* <String, String[]> */optionValues = new HashMap();
23 private final Map<String, String[]> optionValues = new HashMap<>();
2424
2525 private String[] leftOverArgs;
2626
4747 }
4848
4949 public String[] getOptionValues(String option) {
50 return (String[]) optionValues.get(option);
50 return optionValues.get(option);
5151 }
5252
5353 public String[] getLeftOverArgs() {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1919 import java.io.PrintWriter;
2020 import java.util.ArrayList;
2121 import java.util.Arrays;
22 import java.util.Iterator;
2322 import java.util.LinkedHashMap;
23 import java.util.LinkedList;
2424 import java.util.List;
2525 import java.util.ListIterator;
2626 import java.util.Map;
27 import java.util.Map.Entry;
2827
2928 import org.apache.ivy.util.StringUtils;
3029
3332
3433 private static final int MAX_SPEC_WIDTH = 30;
3534
36 private Map/* <String, Option> */options = new LinkedHashMap();
35 private Map<String, Option> options = new LinkedHashMap<>();
3736
38 private Map/* <String, List<Option>> */categories = new LinkedHashMap();
37 private Map<String, List<Option>> categories = new LinkedHashMap<>();
3938
4039 public CommandLineParser() {
4140 }
4241
4342 public CommandLineParser addCategory(String category) {
44 categories.put(category, new ArrayList());
43 categories.put(category, new ArrayList<Option>());
4544 return this;
4645 }
4746
4847 public CommandLineParser addOption(Option option) {
4948 options.put(option.getName(), option);
5049 if (!categories.isEmpty()) {
51 ((List) categories.values().toArray()[categories.values().size() - 1]).add(option);
50 // LinkedHashMap hides its tail...
51 new LinkedList<>(categories.values()).getLast().add(option);
5252 }
5353 return this;
5454 }
5757 CommandLine line = new CommandLine();
5858
5959 int index = args.length;
60 ListIterator iterator = Arrays.asList(args).listIterator();
60 ListIterator<String> iterator = Arrays.asList(args).listIterator();
6161 while (iterator.hasNext()) {
62 String arg = (String) iterator.next();
62 String arg = iterator.next();
6363 if ("--".equals(arg)) {
6464 // skip this argument and stop looping
6565 index = iterator.nextIndex();
7171 break;
7272 }
7373
74 Option option = (Option) options.get(arg.substring(1));
74 Option option = options.get(arg.substring(1));
7575 if (option == null) {
7676 throw new ParseException("Unrecognized option: " + arg);
7777 }
9090 pw.println("usage: " + command);
9191 // compute the largest option spec
9292 int specWidth = 0;
93 for (Iterator iterator = options.values().iterator(); iterator.hasNext();) {
94 Option option = (Option) iterator.next();
93 for (Option option : options.values()) {
9594 if (option.isDeprecated() && !showDeprecated) {
9695 continue;
9796 }
9998 }
10099
101100 // print options help
102 for (Iterator iterator = categories.entrySet().iterator(); iterator.hasNext();) {
103 Entry entry = (Entry) iterator.next();
104 String category = (String) entry.getKey();
105 pw.println("==== " + category);
106 List/* <Option> */options = (List) entry.getValue();
107 for (Iterator it = options.iterator(); it.hasNext();) {
108 Option option = (Option) it.next();
101 for (Map.Entry<String, List<Option>> entry : categories.entrySet()) {
102 pw.println("==== " + entry.getKey());
103 for (Option option : entry.getValue()) {
109104 if (option.isDeprecated() && !showDeprecated) {
110105 continue;
111106 }
116111 pw.print(StringUtils.repeat(" ", specWidth - specLength));
117112
118113 // print description
119 StringBuffer desc = new StringBuffer((option.isDeprecated() ? "DEPRECATED: " : "")
114 StringBuilder desc = new StringBuilder((option.isDeprecated() ? "DEPRECATED: " : "")
120115 + option.getDescription());
121116 int count = Math.min(desc.length(), width - Math.max(specLength, specWidth));
122117 // see if we have enough space to start on the same line as the spec
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
7070 return deprecated;
7171 }
7272
73 String[] parse(ListIterator iterator) throws ParseException {
73 String[] parse(ListIterator<String> iterator) throws ParseException {
7474 if (isCountArgs()) {
7575 String[] values = new String[args.length];
7676 for (int i = 0; i < values.length; i++) {
7777 if (!iterator.hasNext()) {
7878 missingArgument(i);
7979 }
80 values[i] = (String) iterator.next();
80 values[i] = iterator.next();
8181 if (values[i].startsWith("-")) {
8282 missingArgument(i);
8383 }
8484 }
8585 return values;
8686 } else {
87 List values = new ArrayList();
87 List<String> values = new ArrayList<>();
8888 while (iterator.hasNext()) {
89 String value = (String) iterator.next();
89 String value = iterator.next();
9090 if (value.startsWith("-")) {
9191 iterator.previous();
9292 break;
9393 }
9494 values.add(value);
9595 }
96 return (String[]) values.toArray(new String[values.size()]);
96 return values.toArray(new String[values.size()]);
9797 }
9898 }
9999
114114 if (args.length == 0) {
115115 return "";
116116 }
117 StringBuffer sb = new StringBuffer();
118 for (int i = 0; i < args.length; i++) {
119 sb.append("<").append(args[i]).append("> ");
117 StringBuilder sb = new StringBuilder();
118 for (String arg : args) {
119 sb.append("<").append(arg).append("> ");
120120 }
121121 return sb.toString();
122122 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.util.List;
2121
2222 public class OptionBuilder {
23 private String name;
23 private final String name;
2424
25 private List/* <String> */args = new ArrayList();
25 private final List<String> args = new ArrayList<>();
2626
2727 private String description = "";
2828
6262 }
6363
6464 public Option create() {
65 return new Option(name, (String[]) args.toArray(new String[args.size()]), description,
65 return new Option(name, args.toArray(new String[args.size()]), description,
6666 required, countArgs, deprecated);
6767 }
6868 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.cli;
1818
19 @SuppressWarnings("serial")
1920 public class ParseException extends Exception {
2021 public ParseException(String reason) {
2122 super(reason);
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2626 this(null, null);
2727 }
2828
29 public DefaultExtendableItem(Map stdAttributes, Map extraAttributes) {
29 public DefaultExtendableItem(Map<String, String> stdAttributes, Map<String, String> extraAttributes) {
3030 super(stdAttributes, extraAttributes);
3131 }
3232
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2222 /**
2323 * Gets the value of an attribute Can be used to access the value of a standard attribute (like
2424 * organisation, revision) or of an extra attribute.
25 *
25 *
2626 * @param attName
2727 * the name of the attribute to get
2828 * @return the value of the attribute, null if the attribute doesn't exist
3232 /**
3333 * Gets the value of an extra attribute Can be used only to access the value of an extra
3434 * attribute, not a standard one (like organisation, revision)
35 *
35 *
3636 * @param attName
3737 * the name of the extra attribute to get. This name can be either qualified or
3838 * unqualified.
4444 * Returns a Map of all attributes of this extendable item, including standard and extra ones.
4545 * The Map keys are attribute names as Strings, and values are corresponding attribute values
4646 * (as String too). Extra attributes are included in unqualified form only.
47 *
47 *
4848 * @return A Map instance containing all the attributes and their values.
4949 */
50 Map getAttributes();
50 Map<String, String> getAttributes();
5151
5252 /**
5353 * Returns a Map of all extra attributes of this extendable item. The Map keys are
5454 * <b>unqualified</b> attribute names as Strings, and values are corresponding attribute values
5555 * (as String too)
56 *
56 *
5757 * @return A Map instance containing all the extra attributes and their values.
5858 * @see #getQualifiedExtraAttributes()
5959 */
60 Map getExtraAttributes();
60 Map<String, String> getExtraAttributes();
6161
6262 /**
6363 * Returns a Map of all extra attributes of this extendable item.
6969 * An attribute name is qualified with a namespace exactly the same way xml attributes are
7070 * qualified. Thus qualified attribute names are of the form <code>prefix:name</code>
7171 * </p>
72 *
72 *
7373 * @return A Map instance containing all the extra attributes and their values.
7474 * @see #getExtraAttributes()
7575 */
76 Map getQualifiedExtraAttributes();
76 Map<String, String> getQualifiedExtraAttributes();
7777 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1717 package org.apache.ivy.util.extendable;
1818
1919 import java.util.Arrays;
20 import java.util.Collection;
2120 import java.util.HashMap;
22 import java.util.Iterator;
21 import java.util.List;
2322 import java.util.Map;
2423
2524 import org.apache.ivy.plugins.parser.ParserSettings;
2928 private ExtendableItemHelper() {
3029 }
3130
32 public static Map getExtraAttributes(Attributes attributes, String prefix) {
33 Map ret = new HashMap();
31 private static final char separator = '.';
32
33 /**
34 * Decode qualified attribute name from blob.
35 *
36 * @param blob Encoded attribute name
37 * @param prefix Prefix used during encoding
38 * @return String
39 * @see #encodeAttribute(String, String)
40 */
41 public static String decodeAttribute(String blob, String prefix) {
42 // Decoding <qualifier>:<attribute> from
43 // <pre><qlen><sep><qualifier><sep><attribute>
44 // where qualifier (with following separator) is optional.
45 StringBuilder builder = new StringBuilder(blob);
46
47 // Skipping prefix
48 int cur = prefix.length();
49
50 // Resolving length of qualifier
51 int sepi = blob.indexOf(separator, cur);
52 int qlen = Integer.parseInt(blob.substring(cur, sepi));
53
54 // Skipping to attribute and reclaiming ':'
55 cur = sepi + 1;
56 if (qlen > 0)
57 builder.setCharAt(cur + qlen, ':');
58
59 return builder.substring(cur);
60 }
61
62 /**
63 * Encode qualified attribute name into blob
64 * to be used in XML report.
65 *
66 * @param attribute Qualified (or unqualified) attribute name
67 * @param prefix Prefix
68 * @return String
69 * @see #decodeAttribute(String, String)
70 */
71 public static String encodeAttribute(String attribute, String prefix) {
72 StringBuilder builder = new StringBuilder(
73 attribute.length() + prefix.length() + 5
74 );
75
76 // Resolving length of qualifier
77 int coloni = attribute.indexOf(':');
78 int qlen = coloni == -1
79 ? 0
80 : coloni;
81
82 // Encoding <qualifier>:<attribute> as
83 // <pre><qlen><sep><qualifier><sep><attribute>
84 // where qualifier (with following separator) is optional;
85 // e.g. `extra-3.foo.bar` for `foo:bar`, or `extra-0.foo` for `foo`
86 builder.append(prefix);
87 builder.append(qlen);
88 builder.append(separator);
89 builder.append(attribute);
90
91 // Replacing ':' with '.' in order for report XML to not
92 // deal with all those pesky namespaces (c)
93 if (qlen > 0) {
94 int cur = builder.length() - attribute.length();
95 builder.setCharAt(cur + qlen, separator);
96 }
97
98 return builder.toString();
99 }
100
101 public static Map<String, String> getExtraAttributes(Attributes attributes, String prefix) {
102 Map<String, String> ret = new HashMap<>();
34103 for (int i = 0; i < attributes.getLength(); i++) {
35104 if (attributes.getQName(i).startsWith(prefix)) {
36 ret.put(attributes.getQName(i).substring(prefix.length()), attributes.getValue(i));
105 String name = decodeAttribute(attributes.getQName(i), prefix);
106 String value = attributes.getValue(i);
107 ret.put(name, value);
37108 }
38109 }
39110 return ret;
40111 }
41112
113 @Deprecated
114 public static Map<String, String> getExtraAttributes(ParserSettings settings,
115 Attributes attributes, String[] ignoredAttNames) {
116 return getExtraAttributes(settings, attributes, Arrays.asList(ignoredAttNames));
117 }
118
42119 /**
43120 * Extract from the XML attribute the extra Ivy ones
44 *
45 * @param settings
46 * @param attributes
121 *
122 * @param settings ParserSettings
123 * @param attributes Attributes
47124 * @param ignoredAttNames
48125 * the XML attributes names which are not extra but Ivy core ones
49 * @return
126 * @return Map&lt;String,String&gt;
50127 */
51 public static Map getExtraAttributes(ParserSettings settings, Attributes attributes,
52 String[] ignoredAttNames) {
53 Map ret = new HashMap();
54 Collection ignored = Arrays.asList(ignoredAttNames);
128 public static Map<String, String> getExtraAttributes(ParserSettings settings,
129 Attributes attributes, List<String> ignoredAttNames) {
130 Map<String, String> ret = new HashMap<>();
55131 for (int i = 0; i < attributes.getLength(); i++) {
56 if (!ignored.contains(attributes.getQName(i))) {
132 if (!ignoredAttNames.contains(attributes.getQName(i))) {
57133 ret.put(attributes.getQName(i), settings.substitute(attributes.getValue(i)));
58134 }
59135 }
60136 return ret;
61137 }
62138
139 @Deprecated
63140 public static void fillExtraAttributes(ParserSettings settings, DefaultExtendableItem item,
64 Attributes attributes, String[] ignoredAttNames) {
65 Map att = getExtraAttributes(settings, attributes, ignoredAttNames);
66 for (Iterator iter = att.keySet().iterator(); iter.hasNext();) {
67 String attName = (String) iter.next();
68 String attValue = (String) att.get(attName);
69 item.setExtraAttribute(attName, attValue);
141 Attributes attributes, String[] ignoredAttNames) {
142 fillExtraAttributes(settings, item, attributes, Arrays.asList(ignoredAttNames));
143 }
144
145 public static void fillExtraAttributes(ParserSettings settings, DefaultExtendableItem item,
146 Attributes attributes, List<String> ignoredAttNames) {
147 Map<String, String> att = getExtraAttributes(settings, attributes, ignoredAttNames);
148 for (Map.Entry<String, String> entry : att.entrySet()) {
149 item.setExtraAttribute(entry.getKey(), entry.getValue());
70150 }
71151 }
72152
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import java.util.Collections;
2020 import java.util.HashMap;
21 import java.util.Iterator;
2221 import java.util.Map;
23 import java.util.Map.Entry;
2422
2523 public class UnmodifiableExtendableItem implements ExtendableItem {
26 private final Map attributes = new HashMap();
24 private final Map<String, String> attributes = new HashMap<>();
2725
28 private final Map unmodifiableAttributesView = Collections.unmodifiableMap(attributes);
26 private final Map<String, String> unmodifiableAttributesView = Collections
27 .unmodifiableMap(attributes);
2928
30 private final Map extraAttributes = new HashMap();
29 private final Map<String, String> extraAttributes = new HashMap<>();
3130
32 private final Map unmodifiableExtraAttributesView = Collections
31 private final Map<String, String> unmodifiableExtraAttributesView = Collections
3332 .unmodifiableMap(extraAttributes);
3433
3534 /*
3635 * this is the only place where extra attributes are stored in qualified form. In all other maps
3736 * they are stored unqualified.
3837 */
39 private final Map qualifiedExtraAttributes = new HashMap();
38 private final Map<String, String> qualifiedExtraAttributes = new HashMap<>();
4039
41 private final Map unmodifiableQualifiedExtraAttributesView = Collections
40 private final Map<String, String> unmodifiableQualifiedExtraAttributesView = Collections
4241 .unmodifiableMap(qualifiedExtraAttributes);
4342
44 public UnmodifiableExtendableItem(Map stdAttributes, Map extraAttributes) {
43 public UnmodifiableExtendableItem(Map<String, String> stdAttributes,
44 Map<String, String> extraAttributes) {
4545 if (stdAttributes != null) {
4646 this.attributes.putAll(stdAttributes);
4747 }
4848 if (extraAttributes != null) {
49 for (Iterator iter = extraAttributes.entrySet().iterator(); iter.hasNext();) {
50 Entry extraAtt = (Entry) iter.next();
51 setExtraAttribute((String) extraAtt.getKey(), (String) extraAtt.getValue());
49 for (Map.Entry<String, String> extraAtt : extraAttributes.entrySet()) {
50 setExtraAttribute(extraAtt.getKey(), extraAtt.getValue());
5251 }
5352 }
5453 }
5554
5655 public String getAttribute(String attName) {
57 return (String) attributes.get(attName);
56 return attributes.get(attName);
5857 }
5958
6059 public String getExtraAttribute(String attName) {
61 String v = (String) qualifiedExtraAttributes.get(attName);
60 String v = qualifiedExtraAttributes.get(attName);
6261 if (v == null) {
63 v = (String) extraAttributes.get(attName);
62 v = extraAttributes.get(attName);
6463 }
6564 return v;
6665 }
8180 attributes.put(attName, attValue);
8281 }
8382
84 public Map getAttributes() {
83 public Map<String, String> getAttributes() {
8584 return unmodifiableAttributesView;
8685 }
8786
88 public Map getExtraAttributes() {
87 public Map<String, String> getExtraAttributes() {
8988 return unmodifiableExtraAttributesView;
9089 }
9190
92 public Map getQualifiedExtraAttributes() {
91 public Map<String, String> getQualifiedExtraAttributes() {
9392 return unmodifiableQualifiedExtraAttributesView;
9493 }
9594
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.filter;
1818
19 public class AndFilter implements Filter {
20 private Filter op1;
19 public class AndFilter<T> implements Filter<T> {
20 private Filter<T> op1;
2121
22 private Filter op2;
22 private Filter<T> op2;
2323
24 public AndFilter(Filter op1, Filter op2) {
24 public AndFilter(Filter<T> op1, Filter<T> op2) {
2525 this.op1 = op1;
2626 this.op2 = op2;
2727 }
2828
29 public Filter getOp1() {
29 public Filter<T> getOp1() {
3030 return op1;
3131 }
3232
33 public Filter getOp2() {
33 public Filter<T> getOp2() {
3434 return op2;
3535 }
3636
37 public boolean accept(Object o) {
37 public boolean accept(T o) {
3838 return op1.accept(o) && op2.accept(o);
3939 }
4040 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121
2222 import org.apache.ivy.core.module.descriptor.Artifact;
2323
24 public class ArtifactTypeFilter implements Filter {
25 private Collection acceptedTypes;
24 public class ArtifactTypeFilter implements Filter<Artifact> {
25 private Collection<String> acceptedTypes;
2626
27 public ArtifactTypeFilter(Collection acceptedTypes) {
28 this.acceptedTypes = new ArrayList(acceptedTypes);
27 public ArtifactTypeFilter(Collection<String> acceptedTypes) {
28 this.acceptedTypes = new ArrayList<>(acceptedTypes);
2929 }
3030
31 public boolean accept(Object o) {
32 if (!(o instanceof Artifact)) {
33 return false;
34 }
35 Artifact art = (Artifact) o;
31 public boolean accept(Artifact art) {
3632 return acceptedTypes.contains(art.getType());
3733 }
3834 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.filter;
1818
19 public interface Filter {
20 boolean accept(Object o);
19 public interface Filter<T> {
20 boolean accept(T o);
2121 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2121 import java.util.Iterator;
2222 import java.util.List;
2323
24 import org.apache.ivy.core.module.descriptor.Artifact;
25
2426 public final class FilterHelper {
2527 private FilterHelper() {
2628 }
2729
28 public static final Filter NO_FILTER = NoFilter.INSTANCE;
30 public static final Filter<Artifact> NO_FILTER = NoFilter.instance();
2931
30 public static Filter getArtifactTypeFilter(String types) {
32 public static Filter<Artifact> getArtifactTypeFilter(String types) {
3133 if (types == null || types.trim().equals("*")) {
3234 return NO_FILTER;
3335 }
3537 return getArtifactTypeFilter(t);
3638 }
3739
38 public static Filter getArtifactTypeFilter(String[] types) {
40 public static Filter<Artifact> getArtifactTypeFilter(String[] types) {
3941 if (types == null || types.length == 0) {
4042 return NO_FILTER;
4143 }
42 List acceptedTypes = new ArrayList(types.length);
43 for (int i = 0; i < types.length; i++) {
44 String current = types[i].trim();
44 List<String> acceptedTypes = new ArrayList<>(types.length);
45 for (String type : types) {
46 String current = type.trim();
4547 if ("*".equals(current)) {
4648 return NO_FILTER;
4749 }
5153 }
5254
5355 /**
54 * Returns a new collection containing only the items from the given collectoin, which are
55 * accepted by the filter.
56 *
56 * @param <T> The type parameter
5757 * @param col
5858 * The collection to filter.
5959 * @param filter
6060 * The filter to use.
61 * @return A new collection instance containing the only the instance accepted by the filter.
62 *
63 * <br />
64 * Comment: We could have used <a
65 * href="http://jakarta.apache.org/commons/collections/">Commons-Collections</a>
66 * facility for this. If we accepted to add dependencies on third party jars.
61 * @return a new collection instance containing the only the the items from the given
62 * collection, which are accepted by the filter.
63 *
64 * <p>
65 * Comment: We could have used
66 * <a href="https://jakarta.apache.org/commons/collections/">Commons Collections</a> facility for
67 * this, if we accepted additional dependencies on third party jars.
68 * </p>
6769 */
68 public static Collection filter(Collection col, Filter filter) {
70 public static <T> Collection<T> filter(Collection<T> col, Filter<T> filter) {
6971 if (filter == null) {
7072 return col;
7173 }
72 Collection ret = new ArrayList(col);
73 for (Iterator iter = ret.iterator(); iter.hasNext();) {
74 Object element = iter.next();
75 if (!filter.accept(element)) {
74 Collection<T> ret = new ArrayList<>(col);
75 Iterator<T> iter = ret.iterator();
76 while (iter.hasNext()) {
77 if (!filter.accept(iter.next())) {
7678 iter.remove();
7779 }
7880 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.filter;
1818
19 public final class NoFilter implements Filter {
19 public final class NoFilter<T> implements Filter<T> {
20
21 @SuppressWarnings("rawtypes")
2022 public static final Filter INSTANCE = new NoFilter();
23
24 @SuppressWarnings("unchecked")
25 public static <T> Filter<T> instance() {
26 return (Filter<T>) INSTANCE;
27 }
2128
2229 private NoFilter() {
2330 }
2431
25 public boolean accept(Object o) {
32 public boolean accept(T o) {
2633 return true;
2734 }
2835
36 @Override
2937 public String toString() {
3038 return "NoFilter";
3139 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.filter;
1818
19 public class NotFilter implements Filter {
20 private Filter op;
19 public class NotFilter<T> implements Filter<T> {
20 private Filter<T> op;
2121
22 public NotFilter(Filter op) {
22 public NotFilter(Filter<T> op) {
2323 this.op = op;
2424 }
2525
26 public Filter getOp() {
26 public Filter<T> getOp() {
2727 return op;
2828 }
2929
30 public boolean accept(Object o) {
30 public boolean accept(T o) {
3131 return !op.accept(o);
3232 }
3333 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.filter;
1818
19 public class OrFilter implements Filter {
20 private Filter op1;
19 public class OrFilter<T> implements Filter<T> {
20 private Filter<T> op1;
2121
22 private Filter op2;
22 private Filter<T> op2;
2323
24 public OrFilter(Filter op1, Filter op2) {
24 public OrFilter(Filter<T> op1, Filter<T> op2) {
2525 this.op1 = op1;
2626 this.op2 = op2;
2727 }
2828
29 public Filter getOp1() {
29 public Filter<T> getOp1() {
3030 return op1;
3131 }
3232
33 public Filter getOp2() {
33 public Filter<T> getOp2() {
3434 return op2;
3535 }
3636
37 public boolean accept(Object o) {
37 public boolean accept(T o) {
3838 return op1.accept(o) || op2.accept(o);
3939 }
4040 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2929 import java.util.zip.GZIPInputStream;
3030 import java.util.zip.Inflater;
3131 import java.util.zip.InflaterInputStream;
32
3233 import org.apache.ivy.Ivy;
33
34 import org.apache.ivy.core.settings.TimeoutConstraint;
35
36 @SuppressWarnings("deprecation")
3437 public abstract class AbstractURLHandler implements URLHandler {
3538
3639 private static final Pattern ESCAPE_PATTERN = Pattern.compile("%25([0-9a-fA-F][0-9a-fA-F])");
3841 // the request method to use. TODO: don't use a static here
3942 private static int requestMethod = REQUEST_METHOD_HEAD;
4043
41 public boolean isReachable(URL url) {
44 @Override
45 public boolean isReachable(final URL url) {
4246 return getURLInfo(url).isReachable();
4347 }
4448
45 public boolean isReachable(URL url, int timeout) {
49 @Override
50 public boolean isReachable(final URL url, final int timeout) {
4651 return getURLInfo(url, timeout).isReachable();
4752 }
4853
49 public long getContentLength(URL url) {
54 @Override
55 public long getContentLength(final URL url) {
5056 return getURLInfo(url).getContentLength();
5157 }
5258
53 public long getContentLength(URL url, int timeout) {
59 @Override
60 public long getContentLength(final URL url, final int timeout) {
5461 return getURLInfo(url, timeout).getContentLength();
5562 }
5663
57 public long getLastModified(URL url) {
64 @Override
65 public long getLastModified(final URL url) {
5866 return getURLInfo(url).getLastModified();
5967 }
6068
61 public long getLastModified(URL url, int timeout) {
69 @Override
70 public long getLastModified(final URL url, final int timeout) {
6271 return getURLInfo(url, timeout).getLastModified();
6372 }
6473
6574 protected String getUserAgent() {
66 String userAgent = System.getProperty("http.agent");
67 if (userAgent == null) {
68 userAgent = "Apache Ivy/" + Ivy.getIvyVersion();
69 }
70 return userAgent;
75 return System.getProperty("http.agent", "Apache Ivy/" + Ivy.getIvyVersion());
7176 }
7277
7378 protected void validatePutStatusCode(URL dest, int statusCode, String statusMessage)
135140
136141 protected InputStream getDecodingInputStream(String encoding, InputStream in)
137142 throws IOException {
143 if (encoding == null) {
144 return in;
145 }
138146 InputStream result = null;
139
140 if ("gzip".equals(encoding) || "x-gzip".equals(encoding)) {
141 result = new GZIPInputStream(in);
142 } else if ("deflate".equals(encoding)) {
143 // There seems to be 2 variants of the "deflate"-encoding.
144 // I couldn't find a way to auto-detect which variant was
145 // used, so as (a not really good) work-around we try do
146 // decompress the first 100 bytes using the "zlib"-variant.
147 BufferedInputStream bStream = new BufferedInputStream(in);
148 bStream.mark(100);
149 byte[] bytes = new byte[100];
150 int nbBytes = bStream.read(bytes);
151 bStream.reset();
152
153 Inflater inflater = new Inflater();
154 inflater.setInput(bytes, 0, nbBytes);
155 try {
156 inflater.inflate(new byte[1000]);
157
158 // no error decompressing the first 100 bytes, so we
159 // assume the "zlib"-variant was used.
160 result = new InflaterInputStream(bStream);
161 } catch (DataFormatException e) {
162 // there was an error decompressing the first 100 bytes,
163 // so we assume the "gzip/raw"-variant was used.
164 result = new InflaterInputStream(bStream, new Inflater(true));
165 } finally {
166 inflater.end();
147 switch (encoding) {
148 case "deflate":
149 // There seems to be 2 variants of the "deflate"-encoding.
150 // I couldn't find a way to auto-detect which variant was
151 // used, so as (a not really good) work-around we try do
152 // decompress the first 100 bytes using the "zlib"-variant.
153 BufferedInputStream bStream = new BufferedInputStream(in);
154 bStream.mark(100);
155 byte[] bytes = new byte[100];
156 int nbBytes = bStream.read(bytes);
157 bStream.reset();
158
159 Inflater inflater = new Inflater();
160 inflater.setInput(bytes, 0, nbBytes);
161 try {
162 inflater.inflate(new byte[1000]);
163
164 // no error decompressing the first 100 bytes, so we
165 // assume the "zlib"-variant was used.
166 result = new InflaterInputStream(bStream);
167 } catch (DataFormatException e) {
168 // there was an error decompressing the first 100 bytes,
169 // so we assume the "gzip/raw"-variant was used.
170 result = new InflaterInputStream(bStream, new Inflater(true));
171 } finally {
172 inflater.end();
173 }
174 break;
175 case "gzip":
176 case "x-gzip":
177 result = new GZIPInputStream(in);
178 break;
179 default:
180 result = in;
181 break;
182 }
183
184 return result;
185 }
186
187 protected static TimeoutConstraint createTimeoutConstraints(final int connectionTimeout) {
188 return new TimeoutConstraint() {
189 @Override
190 public int getConnectionTimeout() {
191 return connectionTimeout;
167192 }
168 } else {
169 result = in;
170 }
171
172 return result;
173 }
174
193
194 @Override
195 public int getReadTimeout() {
196 return -1;
197 }
198 };
199 }
175200 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2020 import java.io.IOException;
2121 import java.io.InputStream;
2222 import java.io.InputStreamReader;
23 import java.net.URI;
24 import java.net.URISyntaxException;
2325 import java.net.URL;
2426 import java.util.ArrayList;
2527 import java.util.List;
4648
4749 /**
4850 * Returns a list of sub urls of the given url. The returned list is a list of URL.
49 *
51 *
5052 * @param url
5153 * The base URL from which to retrieve the listing.
5254 * @return a list of sub urls of the given url.
5355 * @throws IOException
54 * If an error occures retrieving the HTML.
55 */
56 public List listAll(URL url) throws IOException {
56 * If an error occurs retrieving the HTML.
57 */
58 public List<URL> listAll(URL url) throws IOException {
5759 return retrieveListing(url, true, true);
5860 }
5961
6062 /**
6163 * Returns a list of sub 'directories' of the given url. The returned list is a list of URL.
62 *
64 *
6365 * @param url
6466 * The base URL from which to retrieve the listing.
6567 * @return a list of sub 'directories' of the given url.
6668 * @throws IOException
67 * If an error occures retrieving the HTML.
68 */
69 public List listDirectories(URL url) throws IOException {
69 * If an error occurs retrieving the HTML.
70 */
71 public List<URL> listDirectories(URL url) throws IOException {
7072 return retrieveListing(url, false, true);
7173 }
7274
7375 /**
7476 * Returns a list of sub 'files' (in opposition to directories) of the given url. The returned
7577 * list is a list of URL.
76 *
78 *
7779 * @param url
7880 * The base URL from which to retrieve the listing.
7981 * @return a list of sub 'files' of the given url.
8082 * @throws IOException
81 * If an error occures retrieving the HTML.
82 */
83 public List listFiles(URL url) throws IOException {
83 * If an error occurs retrieving the HTML.
84 */
85 public List<URL> listFiles(URL url) throws IOException {
8486 return retrieveListing(url, true, false);
8587 }
8688
8789 /**
8890 * Retrieves a {@link List} of {@link URL}s corresponding to the files and/or directories found
8991 * at the supplied base URL.
90 *
92 *
9193 * @param url
9294 * The base URL from which to retrieve the listing.
9395 * @param includeFiles
9698 * If true include directories in the returned list.
9799 * @return A {@link List} of {@link URL}s.
98100 * @throws IOException
99 * If an error occures retrieving the HTML.
100 */
101 public List retrieveListing(URL url, boolean includeFiles, boolean includeDirectories)
101 * If an error occurs retrieving the HTML.
102 */
103 @SuppressWarnings("deprecation")
104 public List<URL> retrieveListing(URL url, boolean includeFiles, boolean includeDirectories)
102105 throws IOException {
103 List urlList = new ArrayList();
106 List<URL> urlList = new ArrayList<>();
104107
105108 // add trailing slash for relative urls
106109 if (!url.getPath().endsWith("/") && !url.getPath().endsWith(".html")) {
132135 String href = matcher.group(1);
133136 String text = matcher.group(2);
134137
135 if ((href == null) || (text == null)) {
138 if (href == null || text == null) {
136139 // the groups were not found (shouldn't happen, really)
137140 continue;
138141 }
139142
140143 text = text.trim();
141144
142 // handle complete URL listings
143 if (href.startsWith("http:") || href.startsWith("https:")) {
144 try {
145 href = new URL(href).getPath();
145 try {
146 // URI methods decode the URL
147 URI uri = new URI(href);
148 href = uri.getPath();
149 // handle complete URL listings
150 if (uri.getScheme() != null) {
146151 if (!href.startsWith(url.getPath())) {
147152 // ignore URLs which aren't children of the base URL
148153 continue;
149154 }
150155 href = href.substring(url.getPath().length());
151 } catch (Exception ignore) {
152 // incorrect URL, ignore
153 continue;
154 }
156 }
157 } catch (URISyntaxException e) {
158 // incorrect URL, ignore
159 continue;
155160 }
156161
157162 if (href.startsWith("../")) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1515 *
1616 */
1717 package org.apache.ivy.util.url;
18
19 import org.apache.ivy.core.settings.TimeoutConstraint;
20 import org.apache.ivy.util.CopyProgressListener;
21 import org.apache.ivy.util.FileUtil;
22 import org.apache.ivy.util.Message;
1823
1924 import java.io.ByteArrayInputStream;
2025 import java.io.ByteArrayOutputStream;
2833 import java.net.URLConnection;
2934 import java.net.UnknownHostException;
3035
31 import org.apache.ivy.Ivy;
32 import org.apache.ivy.util.CopyProgressListener;
33 import org.apache.ivy.util.FileUtil;
34 import org.apache.ivy.util.Message;
35
3636 /**
37 *
37 *
3838 */
39 public class BasicURLHandler extends AbstractURLHandler {
39 public class BasicURLHandler extends AbstractURLHandler implements TimeoutConstrainedURLHandler {
4040
4141 private static final int BUFFER_SIZE = 64 * 1024;
4242
4949 }
5050 }
5151
52 public URLInfo getURLInfo(URL url) {
53 return getURLInfo(url, 0);
54 }
55
56 public URLInfo getURLInfo(URL url, int timeout) {
52 @SuppressWarnings("deprecation")
53 @Override
54 public URLInfo getURLInfo(final URL url) {
55 return this.getURLInfo(url, null);
56 }
57
58 @SuppressWarnings("deprecation")
59 @Override
60 public URLInfo getURLInfo(final URL url, final int timeout) {
61 return this.getURLInfo(url, createTimeoutConstraints(timeout));
62 }
63
64 @SuppressWarnings("deprecation")
65 @Override
66 public boolean isReachable(final URL url, final TimeoutConstraint timeoutConstraint) {
67 return this.getURLInfo(url, timeoutConstraint).isReachable();
68 }
69
70 @SuppressWarnings("deprecation")
71 @Override
72 public long getContentLength(final URL url, final TimeoutConstraint timeoutConstraint) {
73 return this.getURLInfo(url, timeoutConstraint).getContentLength();
74 }
75
76 @SuppressWarnings("deprecation")
77 @Override
78 public long getLastModified(final URL url, final TimeoutConstraint timeoutConstraint) {
79 return this.getURLInfo(url, timeoutConstraint).getLastModified();
80 }
81
82 @SuppressWarnings("deprecation")
83 @Override
84 public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
5785 // Install the IvyAuthenticator
5886 if ("http".equals(url.getProtocol()) || "https".equals(url.getProtocol())) {
5987 IvyAuthenticator.install();
6088 }
61
89 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
90 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
6291 URLConnection con = null;
6392 try {
64 url = normalizeToURL(url);
65 con = url.openConnection();
93 final URL normalizedURL = normalizeToURL(url);
94 con = normalizedURL.openConnection();
95 con.setConnectTimeout(connectionTimeout);
96 con.setReadTimeout(readTimeout);
6697 con.setRequestProperty("User-Agent", getUserAgent());
6798 if (con instanceof HttpURLConnection) {
6899 HttpURLConnection httpCon = (HttpURLConnection) con;
69 if (getRequestMethod() == URLHandler.REQUEST_METHOD_HEAD) {
100 if (getRequestMethod() == TimeoutConstrainedURLHandler.REQUEST_METHOD_HEAD) {
70101 httpCon.setRequestMethod("HEAD");
71102 }
72 if (checkStatusCode(url, httpCon)) {
103 if (checkStatusCode(normalizedURL, httpCon)) {
73104 String bodyCharset = getCharSetFromContentType(con.getContentType());
74105 return new URLInfo(true, httpCon.getContentLength(), con.getLastModified(),
75106 bodyCharset);
99130 /**
100131 * Extract the charset from the Content-Type header string, or default to ISO-8859-1 as per
101132 * rfc2616-sec3.html#sec3.7.1 .
102 *
103 * @param contentType
104 * the Content-Type header string
133 *
134 * @param contentType the Content-Type header string
105135 * @return the charset as specified in the content type, or ISO-8859-1 if unspecified.
106136 */
107137 public static String getCharSetFromContentType(String contentType) {
109139 String charSet = null;
110140
111141 if (contentType != null) {
112 String[] elements = contentType.split(";");
113 for (int i = 0; i < elements.length; i++) {
114 String element = elements[i].trim();
142 for (String el : contentType.split(";")) {
143 String element = el.trim();
115144 if (element.toLowerCase().startsWith("charset=")) {
116145 charSet = element.substring("charset=".length());
117146 }
148177 return false;
149178 }
150179
151 public InputStream openStream(URL url) throws IOException {
180 @Override
181 public InputStream openStream(final URL url) throws IOException {
182 return this.openStream(url, null);
183 }
184
185 @Override
186 public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
152187 // Install the IvyAuthenticator
153188 if ("http".equals(url.getProtocol()) || "https".equals(url.getProtocol())) {
154189 IvyAuthenticator.install();
155190 }
191 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
192 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
156193
157194 URLConnection conn = null;
158195 try {
159 url = normalizeToURL(url);
160 conn = url.openConnection();
196 final URL normalizedURL = normalizeToURL(url);
197 conn = normalizedURL.openConnection();
198 conn.setConnectTimeout(connectionTimeout);
199 conn.setReadTimeout(readTimeout);
161200 conn.setRequestProperty("User-Agent", getUserAgent());
162201 conn.setRequestProperty("Accept-Encoding", "gzip,deflate");
163202 if (conn instanceof HttpURLConnection) {
164203 HttpURLConnection httpCon = (HttpURLConnection) conn;
165 if (!checkStatusCode(url, httpCon)) {
166 throw new IOException("The HTTP response code for " + url
204 if (!checkStatusCode(normalizedURL, httpCon)) {
205 throw new IOException("The HTTP response code for " + normalizedURL
167206 + " did not indicate a success." + " See log for more detail.");
168207 }
169208 }
170209 InputStream inStream = getDecodingInputStream(conn.getContentEncoding(),
171 conn.getInputStream());
210 conn.getInputStream());
172211 ByteArrayOutputStream outStream = new ByteArrayOutputStream();
173212
174213 byte[] buffer = new byte[BUFFER_SIZE];
182221 }
183222 }
184223
185 public void download(URL src, File dest, CopyProgressListener l) throws IOException {
224 @Override
225 public void download(final URL src, final File dest, final CopyProgressListener l) throws IOException {
226 this.download(src, dest, l, null);
227 }
228
229 @Override
230 public void download(final URL src, final File dest, final CopyProgressListener listener,
231 final TimeoutConstraint timeoutConstraint) throws IOException {
232
186233 // Install the IvyAuthenticator
187234 if ("http".equals(src.getProtocol()) || "https".equals(src.getProtocol())) {
188235 IvyAuthenticator.install();
189236 }
237 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
238 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
190239
191240 URLConnection srcConn = null;
192241 try {
193 src = normalizeToURL(src);
194 srcConn = src.openConnection();
242 final URL normalizedURL = normalizeToURL(src);
243 srcConn = normalizedURL.openConnection();
244 srcConn.setConnectTimeout(connectionTimeout);
245 srcConn.setReadTimeout(readTimeout);
195246 srcConn.setRequestProperty("User-Agent", getUserAgent());
196247 srcConn.setRequestProperty("Accept-Encoding", "gzip,deflate");
197248 if (srcConn instanceof HttpURLConnection) {
198249 HttpURLConnection httpCon = (HttpURLConnection) srcConn;
199 if (!checkStatusCode(src, httpCon)) {
200 throw new IOException("The HTTP response code for " + src
250 if (!checkStatusCode(normalizedURL, httpCon)) {
251 throw new IOException("The HTTP response code for " + normalizedURL
201252 + " did not indicate a success." + " See log for more detail.");
202253 }
203254 }
204255
205256 // do the download
206257 InputStream inStream = getDecodingInputStream(srcConn.getContentEncoding(),
207 srcConn.getInputStream());
208 FileUtil.copy(inStream, dest, l);
258 srcConn.getInputStream());
259 FileUtil.copy(inStream, dest, listener);
209260
210261 // check content length only if content was not encoded
211262 if (srcConn.getContentEncoding() == null) {
212 int contentLength = srcConn.getContentLength();
213 if (contentLength != -1 && dest.length() != contentLength) {
263 final int contentLength = srcConn.getContentLength();
264 final long destFileSize = dest.length();
265 if (contentLength != -1 && destFileSize != contentLength) {
214266 dest.delete();
215267 throw new IOException(
216 "Downloaded file size doesn't match expected Content Length for " + src
217 + ". Please retry.");
268 "Downloaded file size (" + destFileSize + ") doesn't match expected " +
269 "Content Length (" + contentLength + ") for " + normalizedURL + ". Please retry.");
218270 }
219271 }
220272
228280 }
229281 }
230282
231 public void upload(File source, URL dest, CopyProgressListener l) throws IOException {
283 @Override
284 public void upload(final File source, final URL dest, final CopyProgressListener l) throws IOException {
285 this.upload(source, dest, l, null);
286 }
287
288 @Override
289 public void upload(final File src, final URL dest, final CopyProgressListener listener,
290 final TimeoutConstraint timeoutConstraint) throws IOException {
291
232292 if (!"http".equals(dest.getProtocol()) && !"https".equals(dest.getProtocol())) {
233293 throw new UnsupportedOperationException(
234294 "URL repository only support HTTP PUT at the moment");
237297 // Install the IvyAuthenticator
238298 IvyAuthenticator.install();
239299
300 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
240301 HttpURLConnection conn = null;
241302 try {
242 dest = normalizeToURL(dest);
243 conn = (HttpURLConnection) dest.openConnection();
303 final URL normalizedDestURL = normalizeToURL(dest);
304 conn = (HttpURLConnection) normalizedDestURL.openConnection();
244305 conn.setDoOutput(true);
306 conn.setConnectTimeout(connectionTimeout);
245307 conn.setRequestMethod("PUT");
246308 conn.setRequestProperty("User-Agent", getUserAgent());
247309 conn.setRequestProperty("Content-type", "application/octet-stream");
248 conn.setRequestProperty("Content-length", Long.toString(source.length()));
310 conn.setRequestProperty("Content-length", Long.toString(src.length()));
249311 conn.setInstanceFollowRedirects(true);
250312
251 InputStream in = new FileInputStream(source);
252 try {
253 OutputStream os = conn.getOutputStream();
254 FileUtil.copy(in, os, l);
255 } finally {
256 try {
257 in.close();
258 } catch (IOException e) {
259 /* ignored */
260 }
261 }
262 validatePutStatusCode(dest, conn.getResponseCode(), conn.getResponseMessage());
313 try (final InputStream in = new FileInputStream(src)) {
314 final OutputStream os = conn.getOutputStream();
315 FileUtil.copy(in, os, listener);
316 }
317 validatePutStatusCode(normalizedDestURL, conn.getResponseCode(), conn.getResponseMessage());
263318 } finally {
264319 disconnect(conn);
265320 }
321
266322 }
267323
268324 private void disconnect(URLConnection con) {
291347 private void readResponseBody(HttpURLConnection conn) {
292348 byte[] buffer = new byte[BUFFER_SIZE];
293349
294 InputStream inStream = null;
295 try {
296 inStream = conn.getInputStream();
350 try (InputStream inStream = conn.getInputStream()) {
297351 while (inStream.read(buffer) > 0) {
298352 // Skip content
299353 }
300354 } catch (IOException e) {
301355 // ignore
302 } finally {
303 if (inStream != null) {
304 try {
305 inStream.close();
306 } catch (IOException e) {
307 // ignore
308 }
309 }
310356 }
311357
312358 InputStream errStream = conn.getErrorStream();
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2525 import org.apache.ivy.util.Message;
2626
2727 /**
28 *
28 *
2929 */
3030 public final class CredentialsStore {
3131 /**
3232 * A Map of Credentials objects keyed by the 'key' of the Credentials.
3333 */
34 private static final Map KEYRING = new HashMap();
34 private static final Map<String, Credentials> KEYRING = new HashMap<>();
3535
36 private static final Set SECURED_HOSTS = new HashSet();
36 private static final Set<String> SECURED_HOSTS = new HashSet<>();
3737
3838 public static final CredentialsStore INSTANCE = new CredentialsStore();
3939
5353 public Credentials getCredentials(String realm, String host) {
5454 String key = Credentials.buildKey(realm, host);
5555 Message.debug("try to get credentials for: " + key);
56 return (Credentials) KEYRING.get(key);
56 return KEYRING.get(key);
5757 }
5858
5959 public boolean hasCredentials(String host) {
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.url;
1818
19 import java.io.File;
20 import java.io.FileInputStream;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.OutputStream;
24 import java.net.URL;
25 import java.net.UnknownHostException;
26 import java.text.ParseException;
27 import java.text.SimpleDateFormat;
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.Locale;
31
32 import org.apache.commons.httpclient.Credentials;
33 import org.apache.commons.httpclient.Header;
34 import org.apache.commons.httpclient.HttpClient;
35 import org.apache.commons.httpclient.HttpException;
36 import org.apache.commons.httpclient.HttpMethodBase;
37 import org.apache.commons.httpclient.HttpStatus;
38 import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
39 import org.apache.commons.httpclient.NTCredentials;
40 import org.apache.commons.httpclient.auth.AuthPolicy;
41 import org.apache.commons.httpclient.auth.AuthScheme;
42 import org.apache.commons.httpclient.auth.AuthScope;
43 import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
44 import org.apache.commons.httpclient.auth.CredentialsProvider;
45 import org.apache.commons.httpclient.methods.GetMethod;
46 import org.apache.commons.httpclient.methods.HeadMethod;
47 import org.apache.commons.httpclient.methods.PutMethod;
48 import org.apache.commons.httpclient.methods.RequestEntity;
49 import org.apache.commons.httpclient.params.HttpMethodParams;
50 import org.apache.ivy.Ivy;
19 import org.apache.http.Header;
20 import org.apache.http.HttpEntity;
21 import org.apache.http.HttpResponse;
22 import org.apache.http.HttpStatus;
23 import org.apache.http.auth.AuthSchemeProvider;
24 import org.apache.http.auth.AuthScope;
25 import org.apache.http.auth.Credentials;
26 import org.apache.http.auth.NTCredentials;
27 import org.apache.http.client.CredentialsProvider;
28 import org.apache.http.client.config.AuthSchemes;
29 import org.apache.http.client.config.RequestConfig;
30 import org.apache.http.client.methods.CloseableHttpResponse;
31 import org.apache.http.client.methods.HttpGet;
32 import org.apache.http.client.methods.HttpHead;
33 import org.apache.http.client.methods.HttpPut;
34 import org.apache.http.config.Lookup;
35 import org.apache.http.config.RegistryBuilder;
36 import org.apache.http.conn.HttpClientConnectionManager;
37 import org.apache.http.conn.routing.HttpRoutePlanner;
38 import org.apache.http.entity.ContentType;
39 import org.apache.http.entity.FileEntity;
40 import org.apache.http.impl.auth.BasicSchemeFactory;
41 import org.apache.http.impl.auth.DigestSchemeFactory;
42 import org.apache.http.impl.auth.NTLMSchemeFactory;
43 import org.apache.http.impl.client.CloseableHttpClient;
44 import org.apache.http.impl.client.HttpClients;
45 import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
46 import org.apache.http.impl.conn.SystemDefaultRoutePlanner;
47 import org.apache.ivy.core.settings.TimeoutConstraint;
5148 import org.apache.ivy.util.CopyProgressListener;
5249 import org.apache.ivy.util.FileUtil;
5350 import org.apache.ivy.util.HostUtil;
5451 import org.apache.ivy.util.Message;
5552
53 import java.io.File;
54 import java.io.IOException;
55 import java.io.InputStream;
56 import java.net.ProxySelector;
57 import java.net.URL;
58 import java.nio.charset.Charset;
59 import java.text.ParseException;
60 import java.text.SimpleDateFormat;
61 import java.util.Arrays;
62 import java.util.List;
63 import java.util.Locale;
64 import java.util.concurrent.ConcurrentHashMap;
65
5666 /**
5767 *
5868 */
59 public class HttpClientHandler extends AbstractURLHandler {
69 public class HttpClientHandler extends AbstractURLHandler implements TimeoutConstrainedURLHandler, AutoCloseable {
6070 private static final SimpleDateFormat LAST_MODIFIED_FORMAT = new SimpleDateFormat(
6171 "EEE, d MMM yyyy HH:mm:ss z", Locale.US);
6272
63 // proxy configuration: obtain from system properties
64 private int proxyPort;
65
66 private String proxyHost = null;
67
68 private String proxyUserName = null;
69
70 private String proxyPasswd = null;
71
72 private HttpClientHelper httpClientHelper;
73
74 private static HttpClient httpClient;
73 // A instance of the HttpClientHandler which gets registered to be closed
74 // when the JVM exits
75 static final HttpClientHandler DELETE_ON_EXIT_INSTANCE;
76
77 static {
78 DELETE_ON_EXIT_INSTANCE = new HttpClientHandler();
79 final Thread shutdownHook = new Thread(new Runnable() {
80 @Override
81 public void run() {
82 try {
83 DELETE_ON_EXIT_INSTANCE.close();
84 } catch (Exception e) {
85 // ignore since this is anyway happening during shutdown of the JVM
86 }
87 }
88 });
89 shutdownHook.setName("ivy-httpclient-shutdown-handler");
90 shutdownHook.setDaemon(true);
91 Runtime.getRuntime().addShutdownHook(shutdownHook);
92 }
93
94 private final CloseableHttpClient httpClient;
7595
7696 public HttpClientHandler() {
77 configureProxy();
78 }
79
80 private void configureProxy() {
81 proxyHost = System.getProperty("http.proxyHost");
82 // TODO constant is better ...
83 if (useProxy()) {
84 proxyPort = Integer.parseInt(System.getProperty("http.proxyPort", "80"));
85 proxyUserName = System.getProperty("http.proxyUser");
86 proxyPasswd = System.getProperty("http.proxyPassword");
87 // It seems there is no equivalent in HttpClient for
88 // 'http.nonProxyHosts' property
89 Message.verbose("proxy configured: host=" + proxyHost + " port=" + proxyPort + " user="
90 + proxyUserName);
91 } else {
92 Message.verbose("no proxy configured");
93 }
94 }
95
96 public InputStream openStream(URL url) throws IOException {
97 GetMethod get = doGet(url, 0);
98 if (!checkStatusCode(url, get)) {
99 get.releaseConnection();
100 throw new IOException("The HTTP response code for " + url
101 + " did not indicate a success." + " See log for more detail.");
102 }
103
104 Header encoding = get.getResponseHeader("Content-Encoding");
105 return getDecodingInputStream(encoding == null ? null : encoding.getValue(),
106 get.getResponseBodyAsStream());
107 }
108
109 public void download(URL src, File dest, CopyProgressListener l) throws IOException {
110 GetMethod get = doGet(src, 0);
97 this.httpClient = buildUnderlyingClient();
98 }
99
100 private CloseableHttpClient buildUnderlyingClient() {
101 return HttpClients.custom()
102 .setConnectionManager(createConnectionManager())
103 .setRoutePlanner(createProxyRoutePlanner())
104 .setUserAgent(this.getUserAgent())
105 .setDefaultAuthSchemeRegistry(createAuthSchemeRegistry())
106 .setDefaultCredentialsProvider(new IvyCredentialsProvider())
107 .build();
108 }
109
110 private static HttpRoutePlanner createProxyRoutePlanner() {
111 // use the standard JRE ProxySelector to get proxy information
112 Message.verbose("Using JRE standard ProxySelector for configuring HTTP proxy");
113 return new SystemDefaultRoutePlanner(ProxySelector.getDefault());
114 }
115
116 private static Lookup<AuthSchemeProvider> createAuthSchemeRegistry() {
117 return RegistryBuilder.<AuthSchemeProvider>create().register(AuthSchemes.DIGEST, new DigestSchemeFactory())
118 .register(AuthSchemes.BASIC, new BasicSchemeFactory())
119 .register(AuthSchemes.NTLM, new NTLMSchemeFactory())
120 .build();
121 }
122
123 private static HttpClientConnectionManager createConnectionManager() {
124 return new PoolingHttpClientConnectionManager();
125 }
126
127 private static List<String> getAuthSchemePreferredOrder() {
128 return Arrays.asList(AuthSchemes.DIGEST, AuthSchemes.BASIC, AuthSchemes.NTLM);
129 }
130
131 @Override
132 public InputStream openStream(final URL url) throws IOException {
133 return this.openStream(url, null);
134 }
135
136 @Override
137 public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
138 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
139 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
140 final CloseableHttpResponse response = doGet(url, connectionTimeout, readTimeout);
141 this.requireSuccessStatus(HttpGet.METHOD_NAME, url, response);
142 final Header encoding = this.getContentEncoding(response);
143 return getDecodingInputStream(encoding == null ? null : encoding.getValue(), response.getEntity().getContent());
144 }
145
146 @Override
147 public void download(final URL src, final File dest, final CopyProgressListener l) throws IOException {
148 this.download(src, dest, l, null);
149 }
150
151 @Override
152 public void download(final URL src, final File dest, final CopyProgressListener listener,
153 final TimeoutConstraint timeoutConstraint) throws IOException {
154
155 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
156 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
157 try (final CloseableHttpResponse response = doGet(src, connectionTimeout, readTimeout)) {
158 // We can only figure the content we got is want we want if the status is success.
159 this.requireSuccessStatus(HttpGet.METHOD_NAME, src, response);
160 final Header encoding = this.getContentEncoding(response);
161 try (final InputStream is = getDecodingInputStream(encoding == null ? null : encoding.getValue(),
162 response.getEntity().getContent())) {
163 FileUtil.copy(is, dest, listener);
164 }
165 dest.setLastModified(getLastModified(response));
166 }
167 }
168
169 @Override
170 public void upload(final File src, final URL dest, final CopyProgressListener l) throws IOException {
171 this.upload(src, dest, l, null);
172 }
173
174 @Override
175 public void upload(final File src, final URL dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
176 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
177 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
178 final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout)
179 .setConnectTimeout(connectionTimeout)
180 .setAuthenticationEnabled(hasCredentialsConfigured(dest))
181 .setTargetPreferredAuthSchemes(getAuthSchemePreferredOrder())
182 .setProxyPreferredAuthSchemes(getAuthSchemePreferredOrder())
183 .setExpectContinueEnabled(true)
184 .build();
185 final HttpPut put = new HttpPut(normalizeToString(dest));
186 put.setConfig(requestConfig);
187 put.setEntity(new FileEntity(src));
188 try (final CloseableHttpResponse response = this.httpClient.execute(put)) {
189 validatePutStatusCode(dest, response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase());
190 }
191 }
192
193 @SuppressWarnings("deprecation")
194 @Override
195 public URLInfo getURLInfo(final URL url) {
196 return this.getURLInfo(url, null);
197 }
198
199 @SuppressWarnings("deprecation")
200 @Override
201 public URLInfo getURLInfo(final URL url, final int timeout) {
202 return this.getURLInfo(url, createTimeoutConstraints(timeout));
203 }
204
205 @SuppressWarnings("deprecation")
206 @Override
207 public boolean isReachable(final URL url, final TimeoutConstraint timeoutConstraint) {
208 return this.getURLInfo(url, timeoutConstraint).isReachable();
209 }
210
211 @SuppressWarnings("deprecation")
212 @Override
213 public long getContentLength(final URL url, final TimeoutConstraint timeoutConstraint) {
214 return this.getURLInfo(url, timeoutConstraint).getContentLength();
215 }
216
217 @SuppressWarnings("deprecation")
218 @Override
219 public long getLastModified(final URL url, final TimeoutConstraint timeoutConstraint) {
220 return this.getURLInfo(url, timeoutConstraint).getLastModified();
221 }
222
223 @SuppressWarnings("deprecation")
224 @Override
225 public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
226 final int connectionTimeout = (timeoutConstraint == null || timeoutConstraint.getConnectionTimeout() < 0) ? 0 : timeoutConstraint.getConnectionTimeout();
227 final int readTimeout = (timeoutConstraint == null || timeoutConstraint.getReadTimeout() < 0) ? 0 : timeoutConstraint.getReadTimeout();
228 CloseableHttpResponse response = null;
111229 try {
112 // We can only figure the content we got is want we want if the status is success.
113 if (!checkStatusCode(src, get)) {
114 throw new IOException("The HTTP response code for " + src
115 + " did not indicate a success." + " See log for more detail.");
116 }
117
118 Header encoding = get.getResponseHeader("Content-Encoding");
119 InputStream is = getDecodingInputStream(encoding == null ? null : encoding.getValue(),
120 get.getResponseBodyAsStream());
121 FileUtil.copy(is, dest, l);
122 dest.setLastModified(getLastModified(get));
230 final String httpMethod;
231 if (getRequestMethod() == TimeoutConstrainedURLHandler.REQUEST_METHOD_HEAD) {
232 httpMethod = HttpHead.METHOD_NAME;
233 response = doHead(url, connectionTimeout, readTimeout);
234 } else {
235 httpMethod = HttpGet.METHOD_NAME;
236 response = doGet(url, connectionTimeout, readTimeout);
237 }
238 if (checkStatusCode(httpMethod, url, response)) {
239 final HttpEntity responseEntity = response.getEntity();
240 final Charset charSet = ContentType.getOrDefault(responseEntity).getCharset();
241 return new URLInfo(true, responseEntity == null ? 0 : responseEntity.getContentLength(),
242 getLastModified(response), charSet.name());
243 }
244 } catch (IOException | IllegalArgumentException e) {
245 // IllegalArgumentException is thrown by HttpClient library to indicate the URL is not valid,
246 // this happens for instance when trying to download a dynamic version (cfr IVY-390)
247 Message.error("HttpClientHandler: " + e.getMessage() + " url=" + url);
123248 } finally {
124 get.releaseConnection();
125 }
126 }
127
128 public void upload(File src, URL dest, CopyProgressListener l) throws IOException {
129 HttpClient client = getClient();
130
131 PutMethod put = new PutMethod(normalizeToString(dest));
132 put.setDoAuthentication(useAuthentication(dest) || useProxyAuthentication());
133 put.getParams().setBooleanParameter("http.protocol.expect-continue", true);
134 try {
135 put.setRequestEntity(new FileRequestEntity(src));
136 int statusCode = client.executeMethod(put);
137 validatePutStatusCode(dest, statusCode, null);
138 } finally {
139 put.releaseConnection();
140 }
141 }
142
143 public URLInfo getURLInfo(URL url) {
144 return getURLInfo(url, 0);
145 }
146
147 public URLInfo getURLInfo(URL url, int timeout) {
148 HttpMethodBase method = null;
149 try {
150 if (getRequestMethod() == URLHandler.REQUEST_METHOD_HEAD) {
151 method = doHead(url, timeout);
152 } else {
153 method = doGet(url, timeout);
154 }
155 if (checkStatusCode(url, method)) {
156 return new URLInfo(true, getResponseContentLength(method), getLastModified(method),
157 method.getRequestCharSet());
158 }
159 } catch (HttpException e) {
160 Message.error("HttpClientHandler: " + e.getMessage() + ":" + e.getReasonCode() + "="
161 + e.getReason() + " url=" + url);
162 } catch (UnknownHostException e) {
163 Message.warn("Host " + e.getMessage() + " not found. url=" + url);
164 Message.info("You probably access the destination server through "
165 + "a proxy server that is not well configured.");
166 } catch (IOException e) {
167 Message.error("HttpClientHandler: " + e.getMessage() + " url=" + url);
168 } catch (IllegalArgumentException e) {
169 // thrown by HttpClient to indicate the URL is not valid, this happens for instance
170 // when trying to download a dynamic version (cfr IVY-390)
171 } finally {
172 if (method != null) {
173 method.releaseConnection();
249 if (response != null) {
250 try {
251 response.close();
252 } catch (IOException e) {
253 // ignore
254 }
174255 }
175256 }
176257 return UNAVAILABLE;
177258 }
178259
179 private boolean checkStatusCode(URL url, HttpMethodBase method) throws IOException {
180 int status = method.getStatusCode();
260 private boolean checkStatusCode(final String httpMethod, final URL sourceURL, final HttpResponse response) {
261 final int status = response.getStatusLine().getStatusCode();
181262 if (status == HttpStatus.SC_OK) {
182263 return true;
183264 }
184
185265 // IVY-1328: some servers return a 204 on a HEAD request
186 if ("HEAD".equals(method.getName()) && (status == 204)) {
266 if (HttpHead.METHOD_NAME.equals(httpMethod) && (status == 204)) {
187267 return true;
188268 }
189269
190 Message.debug("HTTP response status: " + status + " url=" + url);
270 Message.debug("HTTP response status: " + status + " url=" + sourceURL);
191271 if (status == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) {
192272 Message.warn("Your proxy requires authentication.");
193273 } else if (String.valueOf(status).startsWith("4")) {
194 Message.verbose("CLIENT ERROR: " + method.getStatusText() + " url=" + url);
274 Message.verbose("CLIENT ERROR: " + response.getStatusLine().getReasonPhrase() + " url=" + sourceURL);
195275 } else if (String.valueOf(status).startsWith("5")) {
196 Message.error("SERVER ERROR: " + method.getStatusText() + " url=" + url);
197 }
198
276 Message.error("SERVER ERROR: " + response.getStatusLine().getReasonPhrase() + " url=" + sourceURL);
277 }
199278 return false;
200279 }
201280
202 private long getLastModified(HttpMethodBase method) {
203 Header header = method.getResponseHeader("last-modified");
204 if (header != null) {
205 String lastModified = header.getValue();
206 try {
207 return LAST_MODIFIED_FORMAT.parse(lastModified).getTime();
208 } catch (ParseException e) {
209 // ignored
210 }
281 /**
282 * Checks the status code of the response and if it's considered as successful response, then
283 * this method just returns back. Else it {@link CloseableHttpResponse#close() closes the
284 * response} and throws an {@link IOException} for the unsuccessful response.
285 *
286 * @param httpMethod The HTTP method that was used for the source request
287 * @param sourceURL The URL of the source request
288 * @param response The response to the source request
289 * @throws IOException Thrown if the response was considered unsuccessful
290 */
291 private void requireSuccessStatus(final String httpMethod, final URL sourceURL, final CloseableHttpResponse response) throws IOException {
292 if (this.checkStatusCode(httpMethod, sourceURL, response)) {
293 return;
294 }
295 // this is now considered an unsuccessful response, so close the response and throw an exception
296 try {
297 response.close();
298 } catch (Exception e) {
299 // log and move on
300 Message.debug("Could not close the HTTP response for url=" + sourceURL, e);
301 }
302 throw new IOException("Failed response to request '" + httpMethod + " " + sourceURL + "' " + response.getStatusLine().getStatusCode()
303 + " - '" + response.getStatusLine().getReasonPhrase());
304 }
305
306 private Header getContentEncoding(final HttpResponse response) {
307 return response.getFirstHeader("Content-Encoding");
308 }
309
310 private long getLastModified(final HttpResponse response) {
311 final Header header = response.getFirstHeader("last-modified");
312 if (header == null) {
211313 return System.currentTimeMillis();
212 } else {
213 return System.currentTimeMillis();
214 }
215 }
216
217 private long getResponseContentLength(HttpMethodBase head) {
218 return getHttpClientHelper().getResponseContentLength(head);
219 }
220
221 private HttpClientHelper getHttpClientHelper() {
222 if (httpClientHelper == null) {
223 // use commons httpclient 3.0 if available
224 try {
225 HttpMethodBase.class.getMethod("getResponseContentLength", new Class[0]);
226 httpClientHelper = new HttpClientHelper3x();
227 Message.verbose("using commons httpclient 3.x helper");
228 } catch (SecurityException e) {
229 Message.verbose("unable to get access to getResponseContentLength of "
230 + "commons-httpclient HeadMethod. Please use commons-httpclient 3.0 or "
231 + "use ivy with sufficient security permissions.");
232 Message.verbose("exception: " + e.getMessage());
233 httpClientHelper = new HttpClientHelper2x();
234 Message.verbose("using commons httpclient 2.x helper");
235 } catch (NoSuchMethodException e) {
236 httpClientHelper = new HttpClientHelper2x();
237 Message.verbose("using commons httpclient 2.x helper");
238 }
239 }
240 return httpClientHelper;
241 }
242
243 public int getHttpClientMajorVersion() {
244 HttpClientHelper helper = getHttpClientHelper();
245 return helper.getHttpClientMajorVersion();
246 }
247
248 private GetMethod doGet(URL url, int timeout) throws IOException {
249 HttpClient client = getClient();
250 client.setTimeout(timeout);
251
252 GetMethod get = new GetMethod(normalizeToString(url));
253 get.setDoAuthentication(useAuthentication(url) || useProxyAuthentication());
254 get.setRequestHeader("Accept-Encoding", "gzip,deflate");
255 client.executeMethod(get);
256 return get;
257 }
258
259 private HeadMethod doHead(URL url, int timeout) throws IOException {
260 HttpClient client = getClient();
261 client.setTimeout(timeout);
262
263 HeadMethod head = new HeadMethod(normalizeToString(url));
264 head.setDoAuthentication(useAuthentication(url) || useProxyAuthentication());
265 client.executeMethod(head);
266 return head;
267 }
268
269 private HttpClient getClient() {
270 if (httpClient == null) {
271 final MultiThreadedHttpConnectionManager connManager = new MultiThreadedHttpConnectionManager();
272 httpClient = new HttpClient(connManager);
273
274 Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
275 public void run() {
276 connManager.shutdown();
277 }
278 }));
279
280 List authPrefs = new ArrayList(3);
281 authPrefs.add(AuthPolicy.DIGEST);
282 authPrefs.add(AuthPolicy.BASIC);
283 authPrefs.add(AuthPolicy.NTLM); // put it at the end to give less priority (IVY-213)
284 httpClient.getParams().setParameter(AuthPolicy.AUTH_SCHEME_PRIORITY, authPrefs);
285
286 if (useProxy()) {
287 httpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
288 if (useProxyAuthentication()) {
289 httpClient.getState().setProxyCredentials(
290 new AuthScope(proxyHost, proxyPort, AuthScope.ANY_REALM),
291 createCredentials(proxyUserName, proxyPasswd));
292 }
293 }
294
295 // user-agent
296 httpClient.getParams().setParameter(HttpMethodParams.USER_AGENT,
297 getUserAgent());
298
299 // authentication
300 httpClient.getParams().setParameter(CredentialsProvider.PROVIDER,
301 new IvyCredentialsProvider());
302 }
303
304 return httpClient;
305 }
306
307 private boolean useProxy() {
308 return proxyHost != null && proxyHost.trim().length() > 0;
309 }
310
311 private boolean useAuthentication(URL url) {
314 }
315 final String lastModified = header.getValue();
316 try {
317 return LAST_MODIFIED_FORMAT.parse(lastModified).getTime();
318 } catch (ParseException e) {
319 // ignored
320 }
321 return System.currentTimeMillis();
322 }
323
324 private CloseableHttpResponse doGet(final URL url, final int connectionTimeout, final int readTimeout) throws IOException {
325 final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout)
326 .setConnectTimeout(connectionTimeout)
327 .setAuthenticationEnabled(hasCredentialsConfigured(url))
328 .setTargetPreferredAuthSchemes(getAuthSchemePreferredOrder())
329 .setProxyPreferredAuthSchemes(getAuthSchemePreferredOrder())
330 .build();
331 final HttpGet httpGet = new HttpGet(normalizeToString(url));
332 httpGet.setConfig(requestConfig);
333 httpGet.addHeader("Accept-Encoding", "gzip,deflate");
334 return this.httpClient.execute(httpGet);
335 }
336
337 private CloseableHttpResponse doHead(final URL url, final int connectionTimeout, final int readTimeout) throws IOException {
338 final RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(readTimeout)
339 .setConnectTimeout(connectionTimeout)
340 .setAuthenticationEnabled(hasCredentialsConfigured(url))
341 .setTargetPreferredAuthSchemes(getAuthSchemePreferredOrder())
342 .setProxyPreferredAuthSchemes(getAuthSchemePreferredOrder())
343 .build();
344 final HttpHead httpHead = new HttpHead(normalizeToString(url));
345 httpHead.setConfig(requestConfig);
346 return this.httpClient.execute(httpHead);
347 }
348
349 private boolean hasCredentialsConfigured(final URL url) {
312350 return CredentialsStore.INSTANCE.hasCredentials(url.getHost());
313351 }
314352
315 private boolean useProxyAuthentication() {
316 return (proxyUserName != null && proxyUserName.trim().length() > 0);
317 }
318
319 private static final class HttpClientHelper3x implements HttpClientHelper {
320 private static final int VERSION = 3;
321
322 private HttpClientHelper3x() {
323 }
324
325 public long getResponseContentLength(HttpMethodBase method) {
326 return method.getResponseContentLength();
327 }
328
329 /**
330 * {@inheritDoc}
331 */
332 public int getHttpClientMajorVersion() {
333 return VERSION;
334 }
335 }
336
337 private static final class HttpClientHelper2x implements HttpClientHelper {
338 private static final int VERSION = 2;
339
340 private HttpClientHelper2x() {
341 }
342
343 public long getResponseContentLength(HttpMethodBase method) {
344 Header header = method.getResponseHeader("Content-Length");
345 if (header != null) {
346 try {
347 return Integer.parseInt(header.getValue());
348 } catch (NumberFormatException e) {
349 Message.verbose("Invalid content-length value: " + e.getMessage());
350 }
351 }
352 return 0;
353 }
354
355 /**
356 * {@inheritDoc}
357 */
358 public int getHttpClientMajorVersion() {
359 return VERSION;
360 }
361 }
362
363 public interface HttpClientHelper {
364 long getResponseContentLength(HttpMethodBase method);
365
366 int getHttpClientMajorVersion();
353 @Override
354 public void close() throws Exception {
355 if (this.httpClient != null) {
356 this.httpClient.close();
357 }
367358 }
368359
369360 private static class IvyCredentialsProvider implements CredentialsProvider {
370361
371 public Credentials getCredentials(AuthScheme scheme, String host, int port, boolean proxy)
372 throws CredentialsNotAvailableException {
373 String realm = scheme.getRealm();
374
375 org.apache.ivy.util.Credentials c = CredentialsStore.INSTANCE.getCredentials(realm,
376 host);
377 if (c != null) {
378 return createCredentials(c.getUserName(), c.getPasswd());
379 }
380
381 return null;
382 }
383 }
384
385 private static Credentials createCredentials(String username, String password) {
386 String user;
387 String domain;
388
389 int backslashIndex = username.indexOf('\\');
390 if (backslashIndex >= 0) {
391 user = username.substring(backslashIndex + 1);
392 domain = username.substring(0, backslashIndex);
393 } else {
394 user = username;
395 domain = System.getProperty("http.auth.ntlm.domain", "");
396 }
397
398 return new NTCredentials(user, password, HostUtil.getLocalHostName(), domain);
399 }
400
401 private static class FileRequestEntity implements RequestEntity {
402 private File file;
403
404 public FileRequestEntity(File file) {
405 this.file = file;
406 }
407
408 public long getContentLength() {
409 return file.length();
410 }
411
412 public String getContentType() {
413 return null;
414 }
415
416 public boolean isRepeatable() {
417 return true;
418 }
419
420 public void writeRequest(OutputStream out) throws IOException {
421 InputStream instream = new FileInputStream(file);
422 try {
423 FileUtil.copy(instream, out, null, false);
424 } finally {
425 instream.close();
426 }
427 }
428 }
429
362 private final ConcurrentHashMap<AuthScope, Credentials> cachedCreds = new ConcurrentHashMap<>();
363
364 @Override
365 public void setCredentials(final AuthScope authscope, final Credentials credentials) {
366 if (authscope == null) {
367 throw new IllegalArgumentException("AuthScope cannot be null");
368 }
369 this.cachedCreds.put(authscope, credentials);
370 }
371
372 @Override
373 public Credentials getCredentials(final AuthScope authscope) {
374 if (authscope == null) {
375 return null;
376 }
377 final String realm = authscope.getRealm();
378 final String host = authscope.getHost();
379 final org.apache.ivy.util.Credentials ivyConfiguredCred = CredentialsStore.INSTANCE.getCredentials(realm, host);
380 if (ivyConfiguredCred == null) {
381 return null;
382 }
383 return createCredentials(ivyConfiguredCred.getUserName(), ivyConfiguredCred.getPasswd());
384 }
385
386 @Override
387 public void clear() {
388 this.cachedCreds.clear();
389 }
390
391 private static Credentials createCredentials(final String username, final String password) {
392 final String user;
393 final String domain;
394 int backslashIndex = username.indexOf('\\');
395 if (backslashIndex >= 0) {
396 user = username.substring(backslashIndex + 1);
397 domain = username.substring(0, backslashIndex);
398 } else {
399 user = username;
400 domain = System.getProperty("http.auth.ntlm.domain", "");
401 }
402 return new NTCredentials(user, password, HostUtil.getLocalHostName(), domain);
403 }
404 }
430405 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
2424 import org.apache.ivy.util.Credentials;
2525 import org.apache.ivy.util.Message;
2626
27 import static org.apache.ivy.util.StringUtils.isNullOrEmpty;
28
2729 /**
28 *
30 *
2931 */
3032 public final class IvyAuthenticator extends Authenticator {
3133
4850 // We will try to use the original authenticator as backup authenticator.
4951 // Since there is no getter available, so try to use some reflection to
5052 // obtain it. If that doesn't work, assume there is no original authenticator
51 Authenticator original = null;
53 Authenticator original = getCurrentAuthenticator();
54
55 if (original instanceof IvyAuthenticator) {
56 return;
57 }
5258
5359 try {
54 Field f = Authenticator.class.getDeclaredField("theAuthenticator");
55 f.setAccessible(true);
56 original = (Authenticator) f.get(null);
57 } catch (Throwable t) {
58 Message.debug("Error occurred while getting the original authenticator: "
59 + t.getMessage());
60 }
61
62 if (!(original instanceof IvyAuthenticator)) {
63 try {
64 Authenticator.setDefault(new IvyAuthenticator(original));
65 } catch (SecurityException e) {
66 if (!securityWarningLogged) {
67 securityWarningLogged = true;
68 Message.warn("Not enough permissions to set the IvyAuthenticator. "
69 + "HTTP(S) authentication will be disabled!");
70 }
60 Authenticator.setDefault(new IvyAuthenticator(original));
61 } catch (SecurityException e) {
62 if (!securityWarningLogged) {
63 securityWarningLogged = true;
64 Message.warn("Not enough permissions to set the IvyAuthenticator. "
65 + "HTTP(S) authentication will be disabled!");
7166 }
7267 }
7368 }
8176
8277 if (isProxyAuthentication()) {
8378 String proxyUser = System.getProperty("http.proxyUser");
84 if ((proxyUser != null) && (proxyUser.trim().length() > 0)) {
79 if (!isNullOrEmpty(proxyUser)) {
8580 String proxyPass = System.getProperty("http.proxyPassword", "");
86 Message.debug("authenicating to proxy server with username [" + proxyUser + "]");
81 Message.debug("authenticating to proxy server with username [" + proxyUser + "]");
8782 result = new PasswordAuthentication(proxyUser, proxyPass.toCharArray());
8883 }
8984 } else {
9893 }
9994 }
10095
101 if ((result == null) && (original != null)) {
96 if (result == null && original != null) {
10297 Authenticator.setDefault(original);
10398 try {
10499 result = Authenticator.requestPasswordAuthentication(getRequestingHost(),
105100 getRequestingSite(), getRequestingPort(), getRequestingProtocol(),
106 getRequestingPrompt(), getRequestingScheme());
101 getRequestingPrompt(), getRequestingScheme(), getRequestingURL(), getRequestorType());
107102 } finally {
108103 Authenticator.setDefault(this);
109104 }
113108 }
114109
115110 /**
116 * Checks if the current authentication request is for the proxy server. This functionality is
117 * not available in JDK1.4, so we check this in a very dirty way which is probably not very
118 * portable, but will work for the SUN 1.4 JDKs.
119 *
120 * @return
111 * The {@link Authenticator} doesn't have API before Java 9 to get hold of the current system
112 * level {@link Authenticator}. This method does a best-effort attempt to try and get hold of
113 * the current {@link Authenticator} in a way that's specific to the implementation of this
114 * method. There's no guarantee that this method will return the current authenticator.
115 * <strong>Note: this method is intended to be used exclusively by tests.</strong>
116 *
117 * @return Returns the currently setup system level {@link Authenticator}. In cases where this
118 * method isn't able to get the current authenticator, this method returns null
119 */
120 static Authenticator getCurrentAuthenticator() {
121 return (getJavaVersion() < 9) ? getTheAuthenticator() : getDefaultAuthenticator();
122 }
123
124 /**
125 * Checks if the current authentication request is for the proxy server.
121126 */
122127 private boolean isProxyAuthentication() {
123 try {
124 // we first try to invoke the getRequestorType() method which is a JDK1.5+ method
125 Method m = Authenticator.class.getDeclaredMethod("getRequestorType", null);
126 Object result = m.invoke(this, null);
127 return "PROXY".equals(String.valueOf(result));
128 } catch (NoSuchMethodException e) {
129 // do nothing, this is a JDK1.5+ method
130 } catch (Throwable t) {
131 Message.debug("Error occurred while checking if the authentication request is for the proxy server: "
132 + t.getMessage());
133 }
134
135 // now we will do something very dirty and analyse the stack trace to see
136 // if this method is called from within the 'getHttpProxyAuthentication' method
137 // or the 'getServerAuthentication' method which are both part of the
138 // sun.net.www.protocol.http.HttpURLConnection class.
139 // This might not work on other 1.4 JVM's!
140 // This code should be removed when Ivy requires JDK1.5+
141 StackTraceElement[] stackTrace = (new Exception()).getStackTrace();
142 for (int i = 0; i < stackTrace.length; i++) {
143 if ("getHttpProxyAuthentication".equals(stackTrace[i].getMethodName())) {
144 return true;
145 }
146 if ("getServerAuthentication".equals(stackTrace[i].getMethodName())) {
147 return false;
148 }
149 }
150
151 // fallback to the Ivy 2.2.0 behavior
152 String proxyHost = System.getProperty("http.proxyHost");
153 return getRequestingHost().equals(proxyHost);
128 return RequestorType.PROXY.equals(getRequestorType());
154129 }
155130
131 private static Authenticator getDefaultAuthenticator() {
132 try {
133 final Method m = Authenticator.class.getDeclaredMethod("getDefault");
134 return (Authenticator) m.invoke(null);
135 } catch (final Throwable t) {
136 handleReflectionException(t);
137 }
138 return null;
139 }
140
141 private static Authenticator getTheAuthenticator() {
142 try {
143 Field f = Authenticator.class.getDeclaredField("theAuthenticator");
144 f.setAccessible(true);
145 return (Authenticator) f.get(null);
146 } catch (final Throwable t) {
147 handleReflectionException(t);
148 }
149 return null;
150 }
151
152 private static void handleReflectionException(final Throwable t) {
153 Message.debug("Error occurred while getting the original authenticator: "
154 + t.getMessage());
155 }
156
157 private static int getJavaVersion() {
158 // See https://docs.oracle.com/javase/8/docs/technotes/guides/versioning/spec/versioning2.html#wp90002
159 final String[] version = System.getProperty("java.specification.version").split("\\.");
160 final int major = Integer.parseInt(version[0]);
161 return major == 1 ? Integer.parseInt(version[1]) : major;
162 }
156163 }
0 /*
1 * Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 package org.apache.ivy.util.url;
19
20 import org.apache.ivy.core.settings.TimeoutConstraint;
21 import org.apache.ivy.util.CopyProgressListener;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.InputStream;
26 import java.net.URL;
27
28 /**
29 * A enhanced version of {@link URLHandler} which respects {@link TimeoutConstraint}s on
30 * the operations dealing with download, upload, reachability checks etc...
31 */
32 @SuppressWarnings("deprecation")
33 public interface TimeoutConstrainedURLHandler extends URLHandler {
34
35 /**
36 * Returns true if the passed <code>URL</code> is reachable. Else returns false. Uses the
37 * passed <code>timeoutConstraint</code> for determining the connectivity to the URL.
38 * <p>
39 * Please use {@link #getURLInfo(URL, TimeoutConstraint)} if more one information about the
40 * <code>url</code> is needed
41 * </p>
42 *
43 * @param url The URL to access
44 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
45 * the timeouts are implementation specific
46 * @return boolean
47 * @since 2.5
48 */
49 boolean isReachable(URL url, TimeoutConstraint timeoutConstraint);
50
51 /**
52 * Returns the number of bytes of data that's available for the resource at the passed
53 * <code>url</code>. Returns 0 if the passed <code>url</code> isn't reachable
54 *
55 * @param url The URL to access
56 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
57 * the timeouts are implementation specific
58 * @return long
59 * @since 2.5
60 */
61 long getContentLength(URL url, TimeoutConstraint timeoutConstraint);
62
63 /**
64 * Returns the last modified timestamp of the resource accessible at the passed
65 * <code>url</code>.
66 * <p>
67 * Please use {@link #getURLInfo(URL, TimeoutConstraint)} if more one information about the
68 * <code>url</code> is needed
69 * </p>
70 *
71 * @param url The URL to access
72 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
73 * the timeouts are implementation specific
74 * @return long
75 * @since 2.5
76 */
77 long getLastModified(URL url, TimeoutConstraint timeoutConstraint);
78
79 /**
80 * Returns the {@link URLInfo} extracted from the given url, or {@link #UNAVAILABLE} when the
81 * url is not reachable. Never returns null.
82 *
83 * @param url The URL for which the information is to be retrieved
84 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
85 * the timeouts are implementation specific
86 * @return URLInfo
87 * @since 2.5
88 */
89 URLInfo getURLInfo(URL url, TimeoutConstraint timeoutConstraint);
90
91 /**
92 * Opens and returns an {@link InputStream} to the passed <code>url</code>.
93 *
94 * @param url The URL to which an {@link InputStream} has to be opened
95 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
96 * the timeouts are implementation specific
97 * @return InputStream
98 * @throws IOException if something goes wrong
99 * @since 2.5
100 */
101 InputStream openStream(URL url, TimeoutConstraint timeoutConstraint) throws IOException;
102
103 /**
104 * Downloads the resource available at <code>src</code> to the target <code>dest</code>
105 *
106 * @param src The source URL to download the resource from
107 * @param dest The destination {@link File} to download the resource to
108 * @param listener The listener that will be notified of the download progress
109 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
110 * the timeouts are implementation specific
111 * @throws IOException if something goes wrong
112 * @since 2.5
113 */
114 void download(URL src, File dest, CopyProgressListener listener, TimeoutConstraint timeoutConstraint) throws IOException;
115
116 /**
117 * Uploads the <code>src</code> {@link File} to the target <code>dest</code> {@link URL}
118 *
119 * @param src The source {@link File} to upload
120 * @param dest The target URL where the {@link File} has to be uploaded
121 * @param listener The listener that will be notified of the upload progress
122 * @param timeoutConstraint The connectivity timeout constraints. Can be null, in which case
123 * the timeouts are implementation specific
124 * @throws IOException if something goes wrong
125 * @since 2.5
126 */
127 void upload(File src, URL dest, CopyProgressListener listener, TimeoutConstraint timeoutConstraint) throws IOException;
128 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.url;
1818
19 import org.apache.ivy.util.CopyProgressListener;
20
1921 import java.io.File;
2022 import java.io.IOException;
2123 import java.io.InputStream;
2224 import java.net.URL;
2325
24 import org.apache.ivy.util.CopyProgressListener;
25
2626 /**
2727 * This interface is responsible for handling some URL manipulation (stream opening, downloading,
2828 * check reachability, ...).
29 * <p>
30 *
31 * @deprecated Starting 2.5.0, the {@link TimeoutConstrainedURLHandler} is preferred in favour of this interface
2932 */
33 @Deprecated
3034 public interface URLHandler {
3135
3236 /**
33 * Using the slower REQUEST method for getting the basic URL infos. Use this when getting errors
34 * behind a problematic/special proxy or firewall chain.
37 * Using the slower REQUEST method for getting the basic URL infos. Use this when getting
38 * errors behind a problematic/special proxy or firewall chain.
3539 */
36 public static final int REQUEST_METHOD_GET = 1;
40 int REQUEST_METHOD_GET = 1;
3741
3842 /**
39 * Using the faster HEAD method for getting the basic URL infos. Works for most common networks.
43 * Using the faster HEAD method for getting the basic URL infos. Works for most common
44 * networks.
4045 */
41 public static final int REQUEST_METHOD_HEAD = 2;
46 int REQUEST_METHOD_HEAD = 2;
4247
43 public static class URLInfo {
48 class URLInfo {
4449 private long contentLength;
4550
4651 private long lastModified;
5459 }
5560
5661 protected URLInfo(boolean available, long contentLength, long lastModified,
57 String bodyCharset) {
62 String bodyCharset) {
5863 this.available = available;
5964 this.contentLength = contentLength;
6065 this.lastModified = lastModified;
7883 }
7984 }
8085
81 public static final URLInfo UNAVAILABLE = new URLInfo(false, 0, 0);
86 URLInfo UNAVAILABLE = new URLInfo(false, 0, 0);
8287
8388 /**
8489 * Please prefer getURLInfo when several infos are needed.
85 *
86 * @param url
87 * the url to check
90 *
91 * @param url the url to check
8892 * @return true if the target is reachable
8993 */
90 public boolean isReachable(URL url);
94 boolean isReachable(URL url);
9195
9296 /**
9397 * Please prefer getURLInfo when several infos are needed.
94 *
95 * @param url
96 * the url to check
98 *
99 * @param url the url to check
100 * @param timeout the timeout in milliseconds
97101 * @return true if the target is reachable
98102 */
99 public boolean isReachable(URL url, int timeout);
100
101 /**
102 * Returns the length of the target if the given url is reachable, and without error code in
103 * case of http urls. Please prefer getURLInfo when several infos are needed.
104 *
105 * @param url
106 * the url to check
107 * @return the length of the target if available, 0 if not reachable
108 */
109 public long getContentLength(URL url);
110
111 /**
112 * Returns the length of the target if the given url is reachable, and without error code in
113 * case of http urls.
114 *
115 * @param url
116 * the url to check
117 * @param timeout
118 * the maximum time before considering an url is not reachable a timeout of zero
119 * indicates no timeout
120 * @return the length of the target if available, 0 if not reachable
121 */
122 public long getContentLength(URL url, int timeout);
103 boolean isReachable(URL url, int timeout);
123104
124105 /**
125106 * Please prefer getURLInfo when several infos are needed.
126 *
127 * @param url
128 * the url to check
129 * @return last modified timestamp of the given url
107 *
108 * @param url the url to check
109 * @return the length of the target if the given url is reachable, 0 otherwise. No error code
110 * in case of http urls.
130111 */
131 public long getLastModified(URL url);
112 long getContentLength(URL url);
113
114 /**
115 * @param url the url to check
116 * @param timeout the maximum time before considering an url is not reachable a
117 * timeout of zero indicates no timeout
118 * @return the length of the target if the given url is reachable, 0 otherwise. No error code
119 * in case of http urls.
120 */
121 long getContentLength(URL url, int timeout);
132122
133123 /**
134124 * Please prefer getURLInfo when several infos are needed.
135 *
136 * @param url
137 * the url to check
125 *
126 * @param url the url to check
138127 * @return last modified timestamp of the given url
139128 */
140 public long getLastModified(URL url, int timeout);
129 long getLastModified(URL url);
141130
142131 /**
143 * Returns the URLInfo of the given url or a {@link #UNAVAILABLE} instance, if the url is not
144 * reachable.
145 *
146 * @param url
147 * The url from which information is retrieved.
148 * @return The URLInfo extracted from the given url, or {@link #UNAVAILABLE} when the url is not
149 * available.
132 * Please prefer getURLInfo when several infos are needed.
133 *
134 * @param url the url to check
135 * @param timeout the timeout in milliseconds
136 * @return last modified timestamp of the given url
150137 */
151 public URLInfo getURLInfo(URL url);
138 long getLastModified(URL url, int timeout);
152139
153140 /**
154 * never returns null, return UNAVAILABLE when url is not reachable
155 *
156 * @param url
157 * The url from which information is retrieved.
158 * @param timeout
159 * The timeout in milliseconds.
160 * @return The URLInfo extracted from the given url, or {@link #UNAVAILABLE} when the url is not
161 * available.
141 * @param url The url from which information is retrieved.
142 * @return The URLInfo extracted from the given url, or {@link #UNAVAILABLE} instance when the
143 * url is not reachable.
162144 */
163 public URLInfo getURLInfo(URL url, int timeout);
145 URLInfo getURLInfo(URL url);
164146
165 public InputStream openStream(URL url) throws IOException;
147 /**
148 * @param url The url from which information is retrieved.
149 * @param timeout The timeout in milliseconds.
150 * @return The URLInfo extracted from the given url, or {@link #UNAVAILABLE} when the url is
151 * not reachable, never null.
152 */
153 URLInfo getURLInfo(URL url, int timeout);
166154
167 public void download(URL src, File dest, CopyProgressListener l) throws IOException;
155 /**
156 * @param url ditto
157 * @return InputStream
158 * @throws IOException if something goes wrong
159 */
160 InputStream openStream(URL url) throws IOException;
168161
169 public void upload(File src, URL dest, CopyProgressListener l) throws IOException;
162 /**
163 * @param src URL
164 * @param dest File
165 * @param l CopyProgressListener
166 * @throws IOException if something goes wrong
167 */
168 void download(URL src, File dest, CopyProgressListener l) throws IOException;
170169
171 public void setRequestMethod(int requestMethod);
170 /**
171 * @param src File
172 * @param dest URL
173 * @param l CopyProgressListener
174 * @throws IOException if something goes wrong
175 */
176 void upload(File src, URL dest, CopyProgressListener l) throws IOException;
177
178 void setRequestMethod(int requestMethod);
172179 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1616 */
1717 package org.apache.ivy.util.url;
1818
19 import org.apache.ivy.core.settings.TimeoutConstraint;
20 import org.apache.ivy.util.CopyProgressListener;
21
1922 import java.io.File;
2023 import java.io.IOException;
2124 import java.io.InputStream;
2225 import java.net.URL;
2326 import java.util.HashMap;
24 import java.util.Iterator;
2527 import java.util.Map;
2628
27 import org.apache.ivy.util.CopyProgressListener;
28
2929 /**
30 * This class is used to dispatch downloading requests
30 * An implementation of {@link URLHandler} which uses an underlying {@link URLHandler} per protocol
31 * and a fallback default {@link URLHandler} for dealing with downloads, uploads and
32 * general reachability checks
3133 */
32 public class URLHandlerDispatcher implements URLHandler {
33 private Map handlers = new HashMap();
34
34 public class URLHandlerDispatcher implements TimeoutConstrainedURLHandler {
35 @SuppressWarnings("deprecation")
36 private final Map<String, URLHandler> handlers = new HashMap<>();
37
38 @SuppressWarnings("deprecation")
3539 private URLHandler defaultHandler = new BasicURLHandler();
3640
3741 public URLHandlerDispatcher() {
3842 }
3943
40 public boolean isReachable(URL url) {
41 return getHandler(url.getProtocol()).isReachable(url);
42 }
43
44 public boolean isReachable(URL url, int timeout) {
45 return getHandler(url.getProtocol()).isReachable(url, timeout);
46 }
47
48 public long getContentLength(URL url) {
49 return getHandler(url.getProtocol()).getContentLength(url);
50 }
51
52 public long getContentLength(URL url, int timeout) {
53 return getHandler(url.getProtocol()).getContentLength(url, timeout);
54 }
55
56 public long getLastModified(URL url) {
57 return getHandler(url.getProtocol()).getLastModified(url);
58 }
59
60 public long getLastModified(URL url, int timeout) {
61 return getHandler(url.getProtocol()).getLastModified(url, timeout);
62 }
63
64 public URLInfo getURLInfo(URL url) {
65 return getHandler(url.getProtocol()).getURLInfo(url);
66 }
67
68 public URLInfo getURLInfo(URL url, int timeout) {
69 return getHandler(url.getProtocol()).getURLInfo(url, timeout);
70 }
71
72 public InputStream openStream(URL url) throws IOException {
73 return getHandler(url.getProtocol()).openStream(url);
74 }
75
76 public void download(URL src, File dest, CopyProgressListener l) throws IOException {
77 getHandler(src.getProtocol()).download(src, dest, l);
78 }
79
80 public void upload(File src, URL dest, CopyProgressListener l) throws IOException {
81 getHandler(dest.getProtocol()).upload(src, dest, l);
82 }
83
44 @Override
45 public boolean isReachable(final URL url) {
46 return this.isReachable(url, null);
47 }
48
49 @Override
50 public boolean isReachable(final URL url, final int timeout) {
51 return this.isReachable(url, createTimeoutConstraints(timeout));
52 }
53
54 @SuppressWarnings("deprecation")
55 @Override
56 public boolean isReachable(final URL url, final TimeoutConstraint timeoutConstraint) {
57 final URLHandler handler = this.getHandler(url.getProtocol());
58 if (handler instanceof TimeoutConstrainedURLHandler) {
59 return ((TimeoutConstrainedURLHandler) handler).isReachable(url, timeoutConstraint);
60 }
61 return handler.isReachable(url, timeoutConstraint != null ? timeoutConstraint.getConnectionTimeout() : 0);
62 }
63
64 @Override
65 public long getContentLength(final URL url) {
66 return this.getContentLength(url, null);
67 }
68
69 @Override
70 public long getContentLength(final URL url, final int timeout) {
71 return this.getContentLength(url, createTimeoutConstraints(timeout));
72 }
73
74 @SuppressWarnings("deprecation")
75 @Override
76 public long getContentLength(final URL url, final TimeoutConstraint timeoutConstraint) {
77 final URLHandler handler = this.getHandler(url.getProtocol());
78 if (handler instanceof TimeoutConstrainedURLHandler) {
79 return ((TimeoutConstrainedURLHandler) handler).getContentLength(url, timeoutConstraint);
80 }
81 return handler.getContentLength(url, timeoutConstraint != null ? timeoutConstraint.getConnectionTimeout() : 0);
82 }
83
84 @Override
85 public long getLastModified(final URL url) {
86 return this.getLastModified(url, null);
87 }
88
89 @Override
90 public long getLastModified(final URL url, final int timeout) {
91 return this.getLastModified(url, createTimeoutConstraints(timeout));
92 }
93
94 @SuppressWarnings("deprecation")
95 @Override
96 public long getLastModified(final URL url, final TimeoutConstraint timeoutConstraint) {
97 final URLHandler handler = this.getHandler(url.getProtocol());
98 if (handler instanceof TimeoutConstrainedURLHandler) {
99 return ((TimeoutConstrainedURLHandler) handler).getLastModified(url, timeoutConstraint);
100 }
101 return handler.getLastModified(url, timeoutConstraint != null ? timeoutConstraint.getConnectionTimeout() : 0);
102 }
103
104 @SuppressWarnings("deprecation")
105 @Override
106 public URLInfo getURLInfo(final URL url) {
107 return this.getURLInfo(url, null);
108 }
109
110 @SuppressWarnings("deprecation")
111 @Override
112 public URLInfo getURLInfo(final URL url, final int timeout) {
113 return this.getURLInfo(url, createTimeoutConstraints(timeout));
114 }
115
116 @SuppressWarnings("deprecation")
117 @Override
118 public URLInfo getURLInfo(final URL url, final TimeoutConstraint timeoutConstraint) {
119 final URLHandler handler = this.getHandler(url.getProtocol());
120 if (handler instanceof TimeoutConstrainedURLHandler) {
121 return ((TimeoutConstrainedURLHandler) handler).getURLInfo(url, timeoutConstraint);
122 }
123 return handler.getURLInfo(url, timeoutConstraint != null ? timeoutConstraint.getConnectionTimeout() : 0);
124 }
125
126 @Override
127 public InputStream openStream(final URL url) throws IOException {
128 return this.openStream(url, null);
129 }
130
131 @SuppressWarnings("deprecation")
132 @Override
133 public InputStream openStream(final URL url, final TimeoutConstraint timeoutConstraint) throws IOException {
134 final URLHandler handler = this.getHandler(url.getProtocol());
135 if (handler instanceof TimeoutConstrainedURLHandler) {
136 return ((TimeoutConstrainedURLHandler) handler).openStream(url, timeoutConstraint);
137 }
138 return handler.openStream(url);
139 }
140
141 @Override
142 public void download(final URL src, final File dest, final CopyProgressListener l) throws IOException {
143 this.download(src, dest, l, null);
144 }
145
146 @SuppressWarnings("deprecation")
147 @Override
148 public void download(final URL src, final File dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
149 final URLHandler handler = this.getHandler(src.getProtocol());
150 if (handler instanceof TimeoutConstrainedURLHandler) {
151 ((TimeoutConstrainedURLHandler) handler).download(src, dest, listener, timeoutConstraint);
152 return;
153 }
154 handler.download(src, dest, listener);
155 }
156
157 @Override
158 public void upload(final File src, final URL dest, final CopyProgressListener l) throws IOException {
159 this.upload(src, dest, l, null);
160 }
161
162 @SuppressWarnings("deprecation")
163 @Override
164 public void upload(final File src, final URL dest, final CopyProgressListener listener, final TimeoutConstraint timeoutConstraint) throws IOException {
165 final URLHandler handler = this.getHandler(dest.getProtocol());
166 if (handler instanceof TimeoutConstrainedURLHandler) {
167 ((TimeoutConstrainedURLHandler) handler).upload(src, dest, listener, timeoutConstraint);
168 return;
169 }
170 handler.upload(src, dest, listener);
171 }
172
173 @SuppressWarnings("deprecation")
84174 public void setRequestMethod(int requestMethod) {
85175 defaultHandler.setRequestMethod(requestMethod);
86 for (Iterator it = handlers.values().iterator(); it.hasNext();) {
87 URLHandler handler = (URLHandler) it.next();
176 for (URLHandler handler : handlers.values()) {
88177 handler.setRequestMethod(requestMethod);
89178 }
90179 }
91180
181 @SuppressWarnings("deprecation")
92182 public void setDownloader(String protocol, URLHandler downloader) {
93183 handlers.put(protocol, downloader);
94184 }
95185
186 @SuppressWarnings("deprecation")
96187 public URLHandler getHandler(String protocol) {
97 URLHandler downloader = (URLHandler) handlers.get(protocol);
188 URLHandler downloader = handlers.get(protocol);
98189 return downloader == null ? defaultHandler : downloader;
99190 }
100191
192 @SuppressWarnings("deprecation")
101193 public URLHandler getDefault() {
102194 return defaultHandler;
103195 }
104196
197 @SuppressWarnings("deprecation")
105198 public void setDefault(URLHandler default1) {
106199 defaultHandler = default1;
107200 }
201
202 private static TimeoutConstraint createTimeoutConstraints(final int connectionTimeout) {
203 return new TimeoutConstraint() {
204 @Override
205 public int getConnectionTimeout() {
206 return connectionTimeout;
207 }
208
209 @Override
210 public int getReadTimeout() {
211 return -1;
212 }
213
214 };
215 }
108216 }
55 * (the "License"); you may not use this file except in compliance with
66 * the License. You may obtain a copy of the License at
77 *
8 * http://www.apache.org/licenses/LICENSE-2.0
8 * https://www.apache.org/licenses/LICENSE-2.0
99 *
1010 * Unless required by applicable law or agreed to in writing, software
1111 * distributed under the License is distributed on an "AS IS" BASIS,
1818
1919 import org.apache.ivy.util.Message;
2020
21 import java.lang.reflect.Field;
22
2123 /**
2224 *
2325 */
2527 private URLHandlerRegistry() {
2628 }
2729
30 @SuppressWarnings("deprecation")
2831 private static URLHandler defaultHandler = new BasicURLHandler();
2932
33 @SuppressWarnings("deprecation")
3034 public static URLHandler getDefault() {
3135 return defaultHandler;
3236 }
3337
34 public static void setDefault(URLHandler def) {
38 @SuppressWarnings("deprecation")
39 public static void setDefault(final URLHandler def) {
3540 defaultHandler = def;
3641 }
3742
3843 /**
39 * This method is used to get appropriate http downloader dependening on Jakarta Commons
44 * This method is used to get appropriate http downloader depending on HttpComponents
4045 * HttpClient availability in classpath, or simply use jdk url handling in other cases.
41 *
46 *
4247 * @return most accurate http downloader
4348 */
44 public static URLHandler getHttp() {
49 public static TimeoutConstrainedURLHandler getHttp() {
4550 try {
46 Class.forName("org.apache.commons.httpclient.HttpClient");
47
48 // temporary fix for IVY-880: only use HttpClientHandler when
49 // http-client-3.x is available
50 Class.forName("org.apache.commons.httpclient.params.HttpClientParams");
51
52 Class handler = Class.forName("org.apache.ivy.util.url.HttpClientHandler");
53 Message.verbose("jakarta commons httpclient detected: using it for http downloading");
54 return (URLHandler) handler.newInstance();
55 } catch (ClassNotFoundException e) {
56 Message.verbose("jakarta commons httpclient not found: using jdk url handling");
57 return new BasicURLHandler();
58 } catch (NoClassDefFoundError e) {
59 Message.verbose("error occurred while loading jakarta commons httpclient: "
51 // check for the presence of HttpComponents HttpClient
52 Class.forName("org.apache.http.client.HttpClient");
53 // load our (wrapper) http handler
54 final Class<?> handler = Class.forName("org.apache.ivy.util.url.HttpClientHandler");
55 // we always use just one instance which is internally registered to be closed
56 // when the JVM exits
57 final Field instance = handler.getDeclaredField("DELETE_ON_EXIT_INSTANCE");
58 return (TimeoutConstrainedURLHandler) instance.get(null);
59 } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) {
60 Message.verbose("Using JDK backed URL handler for HTTP interaction since the "
61 + "Apache HttpComponents HttpClient backed handler couldn't be created due to: "
6062 + e.getMessage());
61 Message.verbose("Using jdk url handling instead.");
62 return new BasicURLHandler();
63 } catch (InstantiationException e) {
64 Message.verbose("couldn't instantiate HttpClientHandler: using jdk url handling");
65 return new BasicURLHandler();
66 } catch (IllegalAccessException e) {
67 Message.verbose("couldn't instantiate HttpClientHandler: using jdk url handling");
6863 return new BasicURLHandler();
6964 }
7065 }
0 # ***************************************************************
1 # * Licensed to the Apache Software Foundation (ASF) under one
2 # * or more contributor license agreements. See the NOTICE file
3 # * distributed with this work for additional information
4 # * regarding copyright ownership. The ASF licenses this file
5 # * to you under the Apache License, Version 2.0 (the
6 # * "License"); you may not use this file except in compliance
7 # * with the License. You may obtain a copy of the License at
8 # *
9 # * https://www.apache.org/licenses/LICENSE-2.0
10 # *
11 # * Unless required by applicable law or agreed to in writing,
12 # * software distributed under the License is distributed on an
13 # * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 # * KIND, either express or implied. See the License for the
15 # * specific language governing permissions and limitations
16 # * under the License.
17 # ***************************************************************
18 target.ivy.version=2.5.0
19 # Following OSGi spec: have to be 3 numbers separated by dots
20 target.ivy.bundle.version=2.5.0
21 # in case we want to add a qualifier such as alpha, beta, etc...
22 # if non empty, add a '_' at the end of the qualifier, so the version would look like 1.2.3.alpha_200901011200
23 # NB: be careful with naming, OSGi orders version alphabetically. Suggested values: alpha_, beta_, cr1_ (for RC-1), final_
24 target.ivy.bundle.version.qualifier=final_
25
26
27 # Versions of dependencies
28 #----------------------------------
29 # 'ant.version' is a built in name containing the version of the current
30 # running Ant, so we could not use that name here.
31 apache-ant.version=1.9.14
32 ant-contrib.version=1.0b3
33 bouncycastle.version=1.62
34 commons-vfs2.version=2.2
35 hamcrest.version=1.3
36 httpclient.version=4.5.9
37 jsch.agentproxy.version=0.0.9
38 jsch.version=0.1.55
39 junit.version=4.12
40 oro.version=2.0.8
41 xmlunit.version=1.6