buildr4osgi 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. data/LICENSE +176 -0
  2. data/NOTICE +6 -0
  3. data/README.rdoc +50 -0
  4. data/Rakefile +45 -0
  5. data/buildr4osgi.gemspec +40 -0
  6. data/lib/buildr4osgi/compile/compiler.rb +54 -0
  7. data/lib/buildr4osgi/compile/ecj-3.4.1.jar +0 -0
  8. data/lib/buildr4osgi/compile.rb +16 -0
  9. data/lib/buildr4osgi/eclipse/feature.rb +271 -0
  10. data/lib/buildr4osgi/eclipse/plugin.rb +22 -0
  11. data/lib/buildr4osgi/eclipse.rb +17 -0
  12. data/lib/buildr4osgi/nature/eclipse.rb +80 -0
  13. data/lib/buildr4osgi/nature/java.rb +32 -0
  14. data/lib/buildr4osgi/nature/nature.rb +156 -0
  15. data/lib/buildr4osgi/nature/osgi.rb +32 -0
  16. data/lib/buildr4osgi/nature/scala.rb +32 -0
  17. data/lib/buildr4osgi/nature.rb +23 -0
  18. data/lib/buildr4osgi/osgi/bundle.rb +275 -0
  19. data/lib/buildr4osgi/osgi/bundle_package.rb +80 -0
  20. data/lib/buildr4osgi/osgi/container.rb +140 -0
  21. data/lib/buildr4osgi/osgi/library_extension.rb +174 -0
  22. data/lib/buildr4osgi/osgi/packaging.rb +129 -0
  23. data/lib/buildr4osgi/osgi/project_extension.rb +324 -0
  24. data/lib/buildr4osgi/osgi/registry.rb +61 -0
  25. data/lib/buildr4osgi/osgi/resolving_strategies.rb +104 -0
  26. data/lib/buildr4osgi/osgi/version.rb +131 -0
  27. data/lib/buildr4osgi/osgi.rb +24 -0
  28. data/lib/buildr4osgi.rb +37 -0
  29. data/rakelib/checks.rake +57 -0
  30. data/rakelib/doc.rake +92 -0
  31. data/rakelib/jekylltask.rb +120 -0
  32. data/rakelib/package.rake +73 -0
  33. data/rakelib/release.rake +149 -0
  34. data/rakelib/rspec.rake +73 -0
  35. data/rakelib/setup.rake +54 -0
  36. data/rakelib/stage.rake +206 -0
  37. data/spec/compile/compiler_spec.rb +30 -0
  38. data/spec/eclipse/feature_spec.rb +295 -0
  39. data/spec/nature/eclipse_spec.rb +46 -0
  40. data/spec/nature/java_spec.rb +45 -0
  41. data/spec/nature/osgi_spec.rb +63 -0
  42. data/spec/nature/scala_spec.rb +45 -0
  43. data/spec/nature_spec.rb +144 -0
  44. data/spec/osgi/bundle_package_spec.rb +32 -0
  45. data/spec/osgi/bundle_spec.rb +202 -0
  46. data/spec/osgi/container_spec.rb +93 -0
  47. data/spec/osgi/library_extension_spec.rb +142 -0
  48. data/spec/osgi/packaging_spec.rb +340 -0
  49. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/ECLIPSEF.RSA +0 -0
  50. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/ECLIPSEF.SF +20 -0
  51. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/MANIFEST.MF +28 -0
  52. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/eclipse.inf +3 -0
  53. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/about.html +28 -0
  54. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/fragment.properties +12 -0
  55. data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/runtime_registry_compatibility.jar +0 -0
  56. data/spec/osgi/project_extension_spec.rb +662 -0
  57. data/spec/osgi/registry_spec.rb +50 -0
  58. data/spec/osgi/version_spec.rb +127 -0
  59. data/spec/spec_helpers.rb +85 -0
  60. data/spec/tmp/remote/eclipse/org.eclipse.debug.ui/3.4.1.v20080811_r341/org.eclipse.debug.ui-3.4.1.v20080811_r341.jar +0 -0
  61. data/spec/tmp/remote/eclipse/org.eclipse.debug.ui/3.4.1.v20080811_r341/org.eclipse.debug.ui-3.4.1.v20080811_r341.pom +82 -0
  62. data/spec/tmp/remote/org/slf4j/jcl104-over-slf4j/1.5.8/jcl104-over-slf4j-1.5.8-sources.jar +0 -0
  63. data/spec/tmp/remote/org/slf4j/jcl104-over-slf4j/1.5.8/jcl104-over-slf4j-1.5.8.jar +0 -0
  64. data/spec/tmp/remote/org/slf4j/jcl104-over-slf4j/1.5.8/jcl104-over-slf4j-1.5.8.pom +30 -0
  65. data/spec/tmp/remote/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8-sources.jar +0 -0
  66. data/spec/tmp/remote/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.jar +0 -0
  67. data/spec/tmp/remote/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.pom +101 -0
  68. data/spec/tmp/remote/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8-sources.jar +0 -0
  69. data/spec/tmp/remote/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar +0 -0
  70. data/spec/tmp/remote/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.pom +56 -0
  71. metadata +142 -0
@@ -0,0 +1,22 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ class ::Buildr::Project
17
+ protected
18
+
19
+ # For now packaging as an OSGi Bundle is equivalent to packaging as an Eclipse plugin.
20
+ alias :package_as_plugin :package_as_bundle
21
+ alias :package_as_plugin_spec :package_as_bundle_spec
22
+ end
@@ -0,0 +1,17 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ require 'buildr4osgi/eclipse/plugin'
17
+ require 'buildr4osgi/eclipse/feature'
@@ -0,0 +1,80 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ module Nature
18
+ module Eclipse
19
+ include Extension
20
+
21
+ def eclipse
22
+ @eclipse ||= Buildr::Nature::Eclipse::Eclipse.new(self)
23
+ @eclipse
24
+ end
25
+
26
+ class Eclipse
27
+
28
+ attr_reader :options
29
+ def initialize(project)
30
+ @options = OptionsFromNatures.new(project)
31
+ end
32
+ end
33
+
34
+ class OptionsFromNatures
35
+ attr_accessor :m2_repo_var, :project #Remove when Eclipse patch in.
36
+
37
+ def initialize(project)
38
+ #super(project) uncomment when the patch for better Eclipse task is in.
39
+ @m2_repo_var = 'M2_REPO'
40
+ @project = project
41
+ end
42
+
43
+ def self.special_attr_accessor(*names)
44
+ names.each { |name|
45
+ module_eval %{
46
+
47
+ def #{name}= (value)
48
+ @#{name} = value.is_a?(Array) ? value : [value]
49
+ end
50
+
51
+ def #{name}
52
+ if @#{name}.nil?
53
+ if (project.parent && !project.parent.eclipse.options._#{name}.nil?)
54
+ @#{name} = project.parent.eclipse.options._#{name}
55
+ else
56
+ @#{name} = project.applicable_natures.collect{|n| n.eclipse.#{name}}.flatten.uniq
57
+ end
58
+ end
59
+ @#{name}
60
+ end
61
+
62
+ protected
63
+
64
+ def _#{name}
65
+ @#{name}
66
+ end
67
+ }
68
+ }
69
+ end
70
+
71
+ special_attr_accessor :natures, :builders, :classpath_containers
72
+
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+ class Buildr::Project
79
+ include Buildr::Nature::Eclipse
80
+ end
@@ -0,0 +1,32 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ class JavaNature < DefaultNature
18
+
19
+ def initialize()
20
+ super(:java)
21
+ eclipse.natures = "org.eclipse.jdt.core.javanature"
22
+ eclipse.builders = "org.eclipse.jdt.core.javabuilder"
23
+ eclipse.classpath_containers = "org.eclipse.jdt.launching.JRE_CONTAINER"
24
+ end
25
+
26
+ def applies(project)
27
+ File.exists? project.path_to(:src, :main, :java)
28
+ end
29
+ end
30
+
31
+ Nature::Registry.add_nature(JavaNature.new)
32
+ end
@@ -0,0 +1,156 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+
18
+ # The nature class is extended into project natures.
19
+ # See for example the JavaNature of the ScalaNature.
20
+ # A nature defines an unique id amonsgt all natures.
21
+ #
22
+ # These fields may be set when initializing an instance:
23
+ # eclipse_builders
24
+ # Used by the Eclipse task to output in .project, a builder being an Eclipse-specific background job to build a project.
25
+ # eclipse_natures
26
+ # Used by the Eclipse task to output in .classpath,
27
+ # an Eclipse nature is an Eclipse-specific concept used by the framework to determine the projects features.
28
+ # classpath_containers
29
+ # Used by the Eclipse task to output in .classpath,
30
+ # it is a special container identified by Eclipse for compilation.
31
+ #
32
+ class DefaultNature
33
+
34
+ class EclipseOptions
35
+
36
+ def self.attr_accessor(*names)
37
+ names.each { |name|
38
+ module_eval %{
39
+ attr_reader :#{name}
40
+
41
+ def #{name}= (value)
42
+ @#{name} = value.is_a?(Array) ? value : [value]
43
+
44
+ end
45
+ }
46
+ }
47
+ end
48
+
49
+ attr_accessor :natures, :builders, :classpath_containers
50
+
51
+ end
52
+
53
+ attr_reader :id, :eclipse
54
+
55
+ def initialize(id)
56
+ @id = id
57
+ @eclipse = EclipseOptions.new
58
+ end
59
+
60
+ # Returns true if the nature applies to the project
61
+ def applies(project)
62
+ false
63
+ end
64
+ end
65
+
66
+ module Nature #:nodoc:
67
+
68
+ # The natures registry
69
+ # This class works as a singleton and contains all the available natures.
70
+ #
71
+ module Registry
72
+
73
+ @registered_natures = Array.new
74
+
75
+ # Adds a nature to the registry.
76
+ # Raises exception if the object provided isn't a Nature
77
+ # or if a Nature instance is already registered with the same id.
78
+ def add_nature(nature, before = nil)
79
+ raise "#{nature} is not a nature!" if (!nature.is_a? DefaultNature)
80
+ raise "A nature with the same id is already present" if (get(nature.id))
81
+ if before.nil?
82
+ @registered_natures << nature
83
+ else
84
+ @registered_natures = @registered_natures.insert(@registered_natures.index(get(before)), nature)
85
+ end
86
+ end
87
+
88
+ # Returns a nature, from its id.
89
+ def get(nature)
90
+ if (nature.is_a? Symbol) then
91
+ @registered_natures.each {|n|
92
+ return n if (n.id == nature)
93
+ }
94
+ elsif (nature.is_a? String) then
95
+ @registered_natures.each {|n|
96
+ return n if (n.id.to_s == nature)
97
+ }
98
+ end
99
+ nil
100
+ end
101
+
102
+ # Returns all available natures
103
+ def all()
104
+ return @registered_natures.dup;
105
+ end
106
+
107
+ module_function :all, :get, :add_nature
108
+ end
109
+
110
+ module NatureExtension
111
+ include Extension
112
+ # Gives the natures defined on the project
113
+ # and the ones that apply on the project.
114
+ def applicable_natures()
115
+ Registry.all().select {|n| (natures.include?(n.id)) || n.applies(self)}
116
+ end
117
+
118
+ # :call-seq:
119
+ # natures => [:n1, :n2]
120
+ #
121
+ # Returns the project's natures.
122
+ #
123
+ # If no natures are defined on the project, the project will look for the
124
+ # natures defined in the parent's project and return them instead.
125
+ #
126
+ def natures
127
+ if @natures.nil?
128
+ if parent
129
+ @natures = parent.natures
130
+ else
131
+ @natures = []
132
+ end
133
+ end
134
+ @natures
135
+ end
136
+
137
+ protected
138
+
139
+ # :call-seq:
140
+ # natures = [n1, n2]
141
+ #
142
+ # Sets the project's natures. Allows you to specify natures by calling
143
+ # this accessor, or with the :natures property when calling #define.
144
+ #
145
+ # You can only set the natures once for a given project.
146
+ def natures=(natures)
147
+ raise 'Cannot set natures twice, or after reading its value' if @natures
148
+ @natures = (natures.is_a? Array) ? natures : [natures]
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ class Buildr::Project
155
+ include Buildr::Nature::NatureExtension
156
+ end
@@ -0,0 +1,32 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ class OSGiNature < DefaultNature
18
+
19
+ def initialize()
20
+ super(:osgi)
21
+ eclipse.natures = "org.eclipse.pde.PluginNature"
22
+ eclipse.builders = ["org.eclipse.pde.ManifestBuilder", "org.eclipse.pde.SchemaBuilder"]
23
+ eclipse.classpath_containers = "org.eclipse.pde.core.requiredPlugins"
24
+ end
25
+
26
+ def applies(project)
27
+ ((File.exists? project.path_to("plugin.xml")) || (File.exists? project.path_to("OSGI-INF")))
28
+ end
29
+ end
30
+
31
+ Nature::Registry.add_nature(OSGiNature.new, :java)
32
+ end
@@ -0,0 +1,32 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module Buildr
17
+ class ScalaNature < DefaultNature
18
+
19
+ def initialize()
20
+ super(:scala)
21
+ eclipse.natures = ["ch.epfl.lamp.sdt.core.scalanature", "org.eclipse.jdt.core.javanature"]
22
+ eclipse.builders = "ch.epfl.lamp.sdt.core.scalabuilder"
23
+ eclipse.classpath_containers = ["ch.epfl.lamp.sdt.launching.SCALA_CONTAINER", "org.eclipse.jdt.launching.JRE_CONTAINER"]
24
+ end
25
+
26
+ def applies(project)
27
+ File.exists? project.path_to(:src, :main, :scala)
28
+ end
29
+ end
30
+
31
+ Nature::Registry.add_nature(ScalaNature.new, :java)
32
+ end
@@ -0,0 +1,23 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ require 'buildr4osgi/nature/nature'
17
+ require 'buildr4osgi/nature/eclipse'
18
+ require 'buildr4osgi/nature/java'
19
+ require 'buildr4osgi/nature/scala'
20
+ require 'buildr4osgi/nature/osgi'
21
+
22
+
23
+
@@ -0,0 +1,275 @@
1
+ # Licensed to the Apache Software Foundation (ASF) under one or more
2
+ # contributor license agreements. See the NOTICE file distributed with this
3
+ # work for additional information regarding copyright ownership. The ASF
4
+ # licenses this file to you under the Apache License, Version 2.0 (the
5
+ # "License"); you may not use this file except in compliance with the License.
6
+ # 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, WITHOUT
12
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13
+ # License for the specific language governing permissions and limitations under
14
+ # the License.
15
+
16
+ module OSGi #:nodoc:
17
+
18
+ OSGI_GROUP_ID = "osgi"
19
+
20
+ # :nodoc:
21
+ # Module extending projects
22
+ # to find which matches criterias used
23
+ # to find bundles.
24
+ #
25
+ module BundleProjectMatcher
26
+
27
+ # Find if the project matches a specific set of criteria passed as parameter
28
+ # The criteria are tested against the manifest of the project, using its bundle packages manifest options and the MANIFEST.MF master file.
29
+ #
30
+ # Returns true if at least one of the packages defined by this project match the criteria.
31
+ #
32
+ def matches(criteria = {:name => "", :version => "", :exports_package => "", :fragment_for => ""})
33
+ if File.exists?(File.join(base_dir, "META-INF", "MANIFEST.MF"))
34
+ manifest = ::Buildr::Packaging::Java::Manifest.new(File.join(base_dir, "META-INF", "MANIFEST.MF"))
35
+ end
36
+ manifest ||= ::Buildr::Packaging::Java::Manifest.new()
37
+ project.packages.select {|package| package.is_a? ::OSGi::BundlePackaging}.each {|p|
38
+ package_manifest = manifest.dup
39
+ package_manifest.main.merge!(p.manifest) if p.manifest
40
+ package_manifest = Manifest.read(package_manifest.to_s)
41
+ if criteria[:exports_package]
42
+ if criteria[:version]
43
+ matchdata = package_manifest.first[Bundle::B_EXPORT_PKG][criteria[:exports_package]] unless package_manifest.first[Bundle::B_EXPORT_PKG].nil?
44
+ return false unless matchdata
45
+ exported_package_version = matchdata["version"]
46
+ if criteria[:version].is_a? VersionRange
47
+ return criteria[:version].in_range(exported_package_version)
48
+ else
49
+ return criteria[:version] == exported_package_version
50
+ end
51
+ else
52
+ return false if package_manifest.first[Bundle::B_EXPORT_PKG].nil?
53
+ return !package_manifest.first[Bundle::B_EXPORT_PKG][criteria[:exports_package]].nil?
54
+ end
55
+ elsif (package_manifest.first[Bundle::B_NAME].keys.first == criteria[:name] || id == criteria[:name])
56
+
57
+ if criteria[:version]
58
+ if criteria[:version].is_a?(VersionRange)
59
+ return criteria[:version].in_range(version)
60
+ else
61
+ return criteria[:version] == version
62
+ end
63
+ else
64
+ # depending just on the name, returning true then.
65
+ return true
66
+ end
67
+ end
68
+ }
69
+ return false
70
+ end
71
+
72
+ end
73
+
74
+ # A bundle is an OSGi artifact represented by a jar file or a folder.
75
+ # It contains a manifest file with specific OSGi headers.
76
+ #
77
+ class Bundle
78
+ include Buildr::ActsAsArtifact
79
+
80
+ #Keys used in the MANIFEST.MF file
81
+ B_NAME = "Bundle-SymbolicName"
82
+ B_REQUIRE = "Require-Bundle"
83
+ B_IMPORT_PKG = "Import-Package"
84
+ B_EXPORT_PKG = "Export-Package"
85
+ B_FRAGMENT_HOST = "Fragment-Host"
86
+ B_VERSION = "Bundle-Version"
87
+ B_DEP_VERSION = "bundle-version"
88
+ B_RESOLUTION = "resolution"
89
+ B_LAZY_START = "Bundle-ActivationPolicy"
90
+ B_OLD_LAZY_START = "Eclipse-LazyStart"
91
+
92
+ # Creates a bundle out of a project, using the manifest defined in its bundle package
93
+ # and the MANIFEST.MF file present in the project if any.
94
+ def self.fromProject(project)
95
+ packaging = project.packages.select {|package| package.is_a?(::OSGi::BundlePackaging)}
96
+ raise "More than one bundle packaging is defined over the project #{project.id}, see BOSGI-16." if packaging.size > 1
97
+ return nil if packaging.empty?
98
+ manifest = ::Buildr::Packaging::Java::Manifest.new(File.exists?("META-INF/MANIFEST.MF") ? File.read("META-INF/MANIFEST.MF") : nil)
99
+ manifest.main.merge!(project.manifest)
100
+ manifest.main.merge!(packaging.first.manifest)
101
+ fromManifest(Manifest.read(manifest.to_s), packaging.first.to_s)
102
+ end
103
+
104
+ # Creates itself by loading from the manifest file passed to it as a hash
105
+ # Finds the name and version, and populates a list of dependencies.
106
+ def self.fromManifest(manifest, jarFile)
107
+ if manifest.first[B_NAME].nil?
108
+ warn "Could not find the name of the bundle represented by #{jarFile}"
109
+ return nil
110
+ end
111
+
112
+ #see http://aspsp.blogspot.com/2008/01/wheressystembundlejarfilecont.html for the system.bundle trick.
113
+ #key.strip: sometimes there is a space between the comma and the name of the bundle.
114
+ #Add the required bundles:
115
+ bundles = []
116
+ manifest.first[B_REQUIRE].each_pair {|key, value| bundles << Bundle.new(key.strip, value[B_DEP_VERSION], {:optional => value[B_RESOLUTION] == "optional"}) unless "system.bundle" == key} unless manifest.first[B_REQUIRE].nil?
117
+ exports = []
118
+ manifest.first[B_EXPORT_PKG].each_pair {|key, value| exports << BundlePackage.new(key.strip, value["version"])} unless manifest.first[B_EXPORT_PKG].nil?
119
+
120
+ #Parse the version
121
+ version = manifest.first[B_VERSION].nil? ? nil : manifest.first[B_VERSION].keys.first
122
+
123
+ #Read the imports
124
+ imports = []
125
+ manifest.first[B_IMPORT_PKG].each_pair {|key, value| imports << BundlePackage.new(key.strip, value["version"], :is_export => false)} unless manifest.first[B_IMPORT_PKG].nil?
126
+
127
+ #Read the imported packages
128
+
129
+ bundle = Bundle.new(manifest.first[B_NAME].keys.first, version, {:file => jarFile, :bundles => bundles, :imports => imports, :exported_packages => exports})
130
+ if !manifest.first[B_LAZY_START].nil?
131
+ # We look for the value of BundleActivationPolicy: lazy or nothing usually.
132
+ # lazy may be spelled Lazy too apparently, so we downcase the string in case.
133
+ bundle.lazy_start = "lazy" == manifest.first[B_LAZY_START].keys.first.strip.downcase
134
+ else
135
+ bundle.lazy_start = "true" == manifest.first[B_OLD_LAZY_START].keys.first.strip unless manifest.first[B_OLD_LAZY_START].nil?
136
+ end
137
+ if (bundle.lazy_start)
138
+ bundle.start_level = 4
139
+ else
140
+ bundle.start_level = 1
141
+ end
142
+
143
+ bundle.fragment = Bundle.new(manifest.first[B_FRAGMENT_HOST].keys.first.strip,
144
+ manifest.first[B_FRAGMENT_HOST].values.first[B_DEP_VERSION]) unless (manifest.first[B_FRAGMENT_HOST].nil?)
145
+ return bundle
146
+ end
147
+
148
+
149
+
150
+ # Attributes of a bundle, derived from its manifest
151
+ # The name is always the symbolic name
152
+ # The version is either the exact version of the bundle or the range in which the bundle would be accepted.
153
+ # The file is the location of the bundle on the disk
154
+ # The optional tag is present on bundles resolved as dependencies, marked as optional.
155
+ # The start level is deduced from the bundles.info file. Default is 1.
156
+ # The lazy start is found in the bundles.info file
157
+ # group is the artifact group used for Maven. By default it is set to OSGI_GROUP_ID.
158
+ # fragment is a Bundle object that represents the fragment host of this bundle (which means this bundle is a fragment if this field is not null).
159
+ # exported_packages is an array of strings representing the packages exported by the bundle.
160
+ # imports is an array of BundlePackage objects representing the packages imported by the bundle.
161
+ attr_accessor :name, :version, :bundles, :file, :optional, :start_level, :lazy_start, :group, :fragment, :exported_packages, :imports
162
+
163
+ alias :id :name
164
+
165
+ def initialize(name, version, args = {:file => nil, :bundles=>[], :imports => [], :optional => false}) #:nodoc:
166
+ @name = name
167
+ @version = VersionRange.parse(version) || (version.nil? ? nil : Version.new(version))
168
+ @bundles = args[:bundles] || []
169
+ @imports = args[:imports] || []
170
+ @exported_packages = args[:exported_packages] || []
171
+ @file = args[:file]
172
+ @optional = args[:optional]
173
+ @start_level = 4
174
+ @type = "jar" #it's always a jar, even if it is a directory: we will jar it for Maven.
175
+ @group = OSGI_GROUP_ID
176
+ end
177
+
178
+
179
+ #
180
+ # Resolves the matching artifacts associated with the project.
181
+ #
182
+ def resolve_matching_artifacts(project)
183
+ # Collect the bundle projects, duplicate them so no changes can be applied to them
184
+ # and extend them with the BundleProjectMatcher module
185
+
186
+ b_projects = OSGi::BundleProjects::bundle_projects.select {|p|
187
+ unless p == project
188
+ p.extend BundleProjectMatcher
189
+ p.matches(:name => name, :version => version)
190
+ end
191
+ }
192
+ #projects take precedence over the dependencies elsewhere, that's what happens in Eclipse
193
+ # for example
194
+ return b_projects unless b_projects.empty?
195
+ return project.osgi.registry.resolved_containers.collect {|i|
196
+ i.find(:name => name, :version => version)
197
+ }.flatten.compact.collect{|b| b.dup }
198
+ end
199
+
200
+ # Returns true if the bundle is an OSGi fragment.
201
+ #
202
+ def fragment?
203
+ !fragment.nil?
204
+ end
205
+
206
+ def to_s #:nodoc:
207
+ to_spec()
208
+ end
209
+
210
+ def to_yaml(opts = {}) #:nodoc:
211
+ to_s.to_yaml(opts)
212
+ end
213
+
214
+ def <=>(other) #:nodoc:
215
+ if other.is_a?(Bundle)
216
+ return to_s <=> other.to_s
217
+ else
218
+ return to_s <=> other
219
+ end
220
+ end
221
+
222
+ # Resolve a bundle from itself, by finding the appropriate bundle in the OSGi containers.
223
+ # Returns self or the project it represents if a project is found to be self.
224
+ #
225
+ def resolve(project, bundles = resolve_matching_artifacts(project))
226
+ bundle = case bundles.size
227
+ when 0 then nil
228
+ when 1 then bundles.first
229
+ else
230
+ OSGi::BundleResolvingStrategies.send(project.osgi.options.bundle_resolving_strategy, bundles)
231
+ end
232
+ if bundle.nil?
233
+ warn "Could not resolve bundle for #{self.to_s}"
234
+ return nil
235
+ end
236
+ return bundle if bundle.is_a?(Buildr::Project)
237
+
238
+ osgi = self.dup
239
+ osgi.name = bundle.name
240
+ osgi.version = bundle.version
241
+ osgi.bundles = bundle.bundles
242
+ osgi.file = bundle.file
243
+ osgi.optional = bundle.optional
244
+ osgi.start_level = bundle.start_level
245
+ osgi.group = bundle.group
246
+
247
+ osgi
248
+ end
249
+
250
+ # Finds the fragments associated with this bundle.
251
+ #
252
+ def fragments(project)
253
+ project.osgi.registry.resolved_containers.collect {|i|
254
+ i.find_fragments(:host => name).select{|f|
255
+ if f.fragment.version.is_a? VersionRange
256
+ f.fragment.version.in_range(version)
257
+ elsif f.fragment.version.nil?
258
+ true
259
+ else
260
+ f.fragment.version == version
261
+ end
262
+ }
263
+ }.flatten.compact.collect{|b| b.dup }
264
+ end
265
+
266
+ # Compares with another bundle and returns true if the name and version match.
267
+ def ==(other) #:nodoc:
268
+ return false unless other.is_a?(Bundle)
269
+ name == other.name && version == other.version
270
+ end
271
+
272
+ alias :eql? ==
273
+
274
+ end
275
+ end