blob: 5ca6afae1bec594fad55817f64d334fa086ab7ae [file] [log] [blame]
Guillaume Nodet8d5faf62010-03-19 15:32:17 +00001/*
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 */
19package org.apache.felix.obrplugin;
20
21import java.io.File;
22import java.io.FileFilter;
23import java.io.FileWriter;
24import java.io.IOException;
25import java.io.Writer;
26import java.net.URI;
27import java.net.URISyntaxException;
28import java.util.ArrayList;
29import java.util.List;
30
31import org.apache.felix.bundlerepository.Property;
32import org.apache.felix.bundlerepository.Resource;
33import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
34import org.apache.felix.bundlerepository.impl.RepositoryImpl;
35import org.apache.felix.bundlerepository.impl.ResourceImpl;
36import org.apache.maven.artifact.repository.ArtifactRepository;
37import org.apache.maven.plugin.AbstractMojo;
38import org.apache.maven.plugin.MojoExecutionException;
39import org.apache.maven.plugin.logging.Log;
40
41/**
42 * Index the content of a maven repository using OBR
43 *
44 * @goal index
45 * @requiresProject false
46 *
47 * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
48 */
49public final class ObrIndex extends AbstractMojo {
50
51 /**
52 * OBR Repository.
53 *
54 * @parameter expression="${obrRepository}"
55 */
56 private String obrRepository;
57
58 /**
59 * Template for urls
60 *
61 * @parameter expression="${urlTemplate}"
62 */
63 private String urlTemplate;
64
65 /**
Guillaume Nodet2d81f332010-04-09 16:29:20 +000066 * The repository to index
67 *
68 * @parameter expression="${mavenRepository}
69 */
70 private String mavenRepository;
71
72 /**
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000073 * Local Repository.
74 *
75 * @parameter expression="${localRepository}"
76 * @required
77 * @readonly
78 */
79 private ArtifactRepository localRepository;
80
81 public void execute() throws MojoExecutionException {
82 Log log = getLog();
83 try
84 {
85 log.info("Indexing...");
86
Guillaume Nodet2d81f332010-04-09 16:29:20 +000087 String repo = mavenRepository;
88 if (repo == null) {
89 repo = localRepository.getBasedir();
90 }
91 URI mavenRepoUri = new File(repo).toURI();
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000092
Guillaume Nodet2d81f332010-04-09 16:29:20 +000093 URI repositoryXml = ObrUtils.findRepositoryXml( repo, obrRepository );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +000094
95 log.info("Repository: " + mavenRepoUri);
96 log.info("OBR xml: " + repositoryXml);
97 log.info("URL template: " + urlTemplate);
98
99 List<File> files = new ArrayList<File>();
100 findAllJars( new File(mavenRepository), files );
101
102 DataModelHelperImpl dmh = new DataModelHelperImpl();
Guillaume Nodet2d81f332010-04-09 16:29:20 +0000103 RepositoryImpl repository;
104
105 File obrRepoFile = new File(repositoryXml);
106 if (obrRepoFile.isFile()) {
107 repository = (RepositoryImpl) dmh.repository( repositoryXml.toURL() );
108 } else {
109 repository = new RepositoryImpl();
110 }
111
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000112 for (File file : files)
113 {
114 try
115 {
116 ResourceImpl resource = (ResourceImpl) dmh.createResource(file.toURI().toURL());
117 if (resource != null)
118 {
119 repository.addResource(resource);
120 doTemplate(mavenRepoUri, file, resource);
121 log.info("Adding resource: " + file);
122 }
123 else
124 {
125 log.info("Ignoring non OSGi bundle: " + file);
126 }
127 }
128 catch (Exception e)
129 {
Guillaume Nodet9337c342010-03-25 08:20:44 +0000130 log.warn("Error processing bundle: " + file + " " + e.getMessage());
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000131 }
132 }
Guillaume Nodet2d81f332010-04-09 16:29:20 +0000133 Writer writer = new FileWriter( obrRepoFile );
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000134 try
135 {
136 dmh.writeRepository( repository, writer );
137 }
138 finally
139 {
140 writer.close();
141 }
142 }
143 catch ( Exception e )
144 {
145 log.warn( "Exception while updating local OBR: " + e.getLocalizedMessage(), e );
146 }
147 }
148
149 protected void doTemplate(URI root, File path, ResourceImpl resource) throws IOException, URISyntaxException
150 {
151 path = path.getAbsoluteFile().getCanonicalFile();
152 String finalUri = root.relativize(path.toURI()).toString();
153 if ("maven".equals(urlTemplate))
154 {
155 String dir = root.relativize(path.toURI()).toString();
156 String[] p = dir.split("/");
157 if (p.length >= 4 && p[p.length-1].startsWith(p[p.length-3] + "-" + p[p.length-2]))
158 {
159 String artifactId = p[p.length-3];
160 String version = p[p.length-2];
161 String classifier;
162 String type;
163 String artifactIdVersion = artifactId + "-" + version;
164 StringBuffer sb = new StringBuffer();
165 if (p[p.length-1].charAt(artifactIdVersion.length()) == '-')
166 {
167 classifier = p[p.length-1].substring(artifactIdVersion.length() + 1, p[p.length-1].lastIndexOf('.'));
168 }
169 else
170 {
171 classifier = null;
172 }
173 type = p[p.length-1].substring(p[p.length-1].lastIndexOf('.') + 1);
174 sb.append("mvn:");
175 for (int j = 0; j < p.length - 3; j++)
176 {
177 if (j > 0)
178 {
179 sb.append('.');
180 }
181 sb.append(p[j]);
182 }
183 sb.append('/').append(artifactId).append('/').append(version);
184 if (!"jar".equals(type) || classifier != null)
185 {
186 sb.append('/');
187 if (!"jar".equals(type))
188 {
189 sb.append(type);
190 }
191 if (classifier != null)
192 {
193 sb.append('/').append(classifier);
194 }
195 }
196 finalUri = sb.toString();
197 }
198 }
Guillaume Nodet9337c342010-03-25 08:20:44 +0000199 else if (urlTemplate != null)
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000200 {
201 String dir = path.getParentFile().toURI().toURL().toString();
202 if (dir.endsWith("/"))
203 dir = dir.substring(0, dir.length() - 1);
204
205 if (dir.startsWith(root.toString()))
206 dir = dir.substring(root.toString().length());
207
208 String url = urlTemplate.replaceAll("%v", "" + resource.getVersion());
209 url = url.replaceAll("%s", resource.getSymbolicName());
210 url = url.replaceAll("%f", path.getName());
211 url = url.replaceAll("%p", dir);
212 finalUri = url;
213 }
214 resource.put(Resource.URI, finalUri, Property.URI);
215 }
216
217 private final FileFilter filter = new FileFilter() {
218
219 public boolean accept(File pathname) {
Guillaume Nodet9337c342010-03-25 08:20:44 +0000220 return pathname.getName().endsWith("ar");
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000221 }
Guillaume Nodet8d5faf62010-03-19 15:32:17 +0000222 };
223
224
225 private void findAllJars(File mainRoot, List<File> files) {
226 List<File> roots = new ArrayList<File>();
227 roots.add(mainRoot);
228 while (!roots.isEmpty()) {
229 File root = roots.remove(0);
230 File[] children = root.listFiles();
231 if (children != null) {
232 for (File child : children) {
233 if (child.isFile() && filter.accept(child)) {
234 files.add(child);
235 } else if (child.isDirectory()) {
236 roots.add(child);
237 }
238 }
239 }
240 }
241 }
242
243}