buildr4osgi 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +176 -0
- data/NOTICE +6 -0
- data/README.rdoc +50 -0
- data/Rakefile +45 -0
- data/buildr4osgi.gemspec +40 -0
- data/lib/buildr4osgi/compile/compiler.rb +54 -0
- data/lib/buildr4osgi/compile/ecj-3.4.1.jar +0 -0
- data/lib/buildr4osgi/compile.rb +16 -0
- data/lib/buildr4osgi/eclipse/feature.rb +271 -0
- data/lib/buildr4osgi/eclipse/plugin.rb +22 -0
- data/lib/buildr4osgi/eclipse.rb +17 -0
- data/lib/buildr4osgi/nature/eclipse.rb +80 -0
- data/lib/buildr4osgi/nature/java.rb +32 -0
- data/lib/buildr4osgi/nature/nature.rb +156 -0
- data/lib/buildr4osgi/nature/osgi.rb +32 -0
- data/lib/buildr4osgi/nature/scala.rb +32 -0
- data/lib/buildr4osgi/nature.rb +23 -0
- data/lib/buildr4osgi/osgi/bundle.rb +275 -0
- data/lib/buildr4osgi/osgi/bundle_package.rb +80 -0
- data/lib/buildr4osgi/osgi/container.rb +140 -0
- data/lib/buildr4osgi/osgi/library_extension.rb +174 -0
- data/lib/buildr4osgi/osgi/packaging.rb +129 -0
- data/lib/buildr4osgi/osgi/project_extension.rb +324 -0
- data/lib/buildr4osgi/osgi/registry.rb +61 -0
- data/lib/buildr4osgi/osgi/resolving_strategies.rb +104 -0
- data/lib/buildr4osgi/osgi/version.rb +131 -0
- data/lib/buildr4osgi/osgi.rb +24 -0
- data/lib/buildr4osgi.rb +37 -0
- data/rakelib/checks.rake +57 -0
- data/rakelib/doc.rake +92 -0
- data/rakelib/jekylltask.rb +120 -0
- data/rakelib/package.rake +73 -0
- data/rakelib/release.rake +149 -0
- data/rakelib/rspec.rake +73 -0
- data/rakelib/setup.rake +54 -0
- data/rakelib/stage.rake +206 -0
- data/spec/compile/compiler_spec.rb +30 -0
- data/spec/eclipse/feature_spec.rb +295 -0
- data/spec/nature/eclipse_spec.rb +46 -0
- data/spec/nature/java_spec.rb +45 -0
- data/spec/nature/osgi_spec.rb +63 -0
- data/spec/nature/scala_spec.rb +45 -0
- data/spec/nature_spec.rb +144 -0
- data/spec/osgi/bundle_package_spec.rb +32 -0
- data/spec/osgi/bundle_spec.rb +202 -0
- data/spec/osgi/container_spec.rb +93 -0
- data/spec/osgi/library_extension_spec.rb +142 -0
- data/spec/osgi/packaging_spec.rb +340 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/ECLIPSEF.RSA +0 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/ECLIPSEF.SF +20 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/MANIFEST.MF +28 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/META-INF/eclipse.inf +3 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/about.html +28 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/fragment.properties +12 -0
- data/spec/osgi/plugins/org.eclipse.core.runtime.compatibility.registry_3.2.200.v20090429-1800/runtime_registry_compatibility.jar +0 -0
- data/spec/osgi/project_extension_spec.rb +662 -0
- data/spec/osgi/registry_spec.rb +50 -0
- data/spec/osgi/version_spec.rb +127 -0
- data/spec/spec_helpers.rb +85 -0
- 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
- 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
- data/spec/tmp/remote/org/slf4j/jcl104-over-slf4j/1.5.8/jcl104-over-slf4j-1.5.8-sources.jar +0 -0
- data/spec/tmp/remote/org/slf4j/jcl104-over-slf4j/1.5.8/jcl104-over-slf4j-1.5.8.jar +0 -0
- data/spec/tmp/remote/org/slf4j/jcl104-over-slf4j/1.5.8/jcl104-over-slf4j-1.5.8.pom +30 -0
- data/spec/tmp/remote/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8-sources.jar +0 -0
- data/spec/tmp/remote/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.jar +0 -0
- data/spec/tmp/remote/org/slf4j/slf4j-api/1.5.8/slf4j-api-1.5.8.pom +101 -0
- data/spec/tmp/remote/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8-sources.jar +0 -0
- data/spec/tmp/remote/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.jar +0 -0
- data/spec/tmp/remote/org/slf4j/slf4j-log4j12/1.5.8/slf4j-log4j12-1.5.8.pom +56 -0
- 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
|