1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.felix.obrplugin;
20
21
22 import java.io.File;
23 import java.io.FileFilter;
24 import java.io.FileWriter;
25 import java.io.IOException;
26 import java.io.Writer;
27 import java.net.URI;
28 import java.net.URISyntaxException;
29 import java.util.ArrayList;
30 import java.util.List;
31
32 import org.apache.felix.bundlerepository.Property;
33 import org.apache.felix.bundlerepository.Resource;
34 import org.apache.felix.bundlerepository.impl.DataModelHelperImpl;
35 import org.apache.felix.bundlerepository.impl.RepositoryImpl;
36 import org.apache.felix.bundlerepository.impl.ResourceImpl;
37 import org.apache.maven.artifact.repository.ArtifactRepository;
38 import org.apache.maven.plugin.AbstractMojo;
39 import org.apache.maven.plugin.MojoExecutionException;
40 import org.apache.maven.plugin.logging.Log;
41 import org.apache.maven.plugins.annotations.Mojo;
42 import org.apache.maven.plugins.annotations.Parameter;
43
44
45
46
47
48
49
50 @Mojo( name = "index", requiresProject = false )
51 public final class ObrIndex extends AbstractMojo
52 {
53
54
55
56
57 @Parameter( property = "obrRepository" )
58 private String obrRepository;
59
60
61
62
63 @Parameter( property = "urlTemplate" )
64 private String urlTemplate;
65
66
67
68
69 @Parameter( property = "mavenRepository" )
70 private String mavenRepository;
71
72
73
74
75 @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
76 private ArtifactRepository localRepository;
77
78
79 public void execute() throws MojoExecutionException
80 {
81 Log log = getLog();
82 try
83 {
84 log.info( "Indexing..." );
85
86 String repo = mavenRepository;
87 if ( repo == null )
88 {
89 repo = localRepository.getBasedir();
90 }
91 URI mavenRepoUri = new File( repo ).toURI();
92
93 URI repositoryXml = ObrUtils.findRepositoryXml( repo, obrRepository );
94
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( repo ), files );
101
102 DataModelHelperImpl dmh = new DataModelHelperImpl();
103 RepositoryImpl repository;
104
105 File obrRepoFile = new File( repositoryXml );
106 if ( obrRepoFile.isFile() )
107 {
108 repository = ( RepositoryImpl ) dmh.repository( repositoryXml.toURL() );
109 }
110 else
111 {
112 repository = new RepositoryImpl();
113 }
114
115 for ( File file : files )
116 {
117 try
118 {
119 ResourceImpl resource = ( ResourceImpl ) dmh.createResource( file.toURI().toURL() );
120 if ( resource != null )
121 {
122 repository.addResource( resource );
123 doTemplate( mavenRepoUri, file, resource );
124 log.info( "Adding resource: " + file );
125 }
126 else
127 {
128 log.info( "Ignoring non OSGi bundle: " + file );
129 }
130 }
131 catch ( Exception e )
132 {
133 log.warn( "Error processing bundle: " + file + " " + e.getMessage() );
134 }
135 }
136 Writer writer = new FileWriter( obrRepoFile );
137 try
138 {
139 dmh.writeRepository( repository, writer );
140 }
141 finally
142 {
143 writer.close();
144 }
145 }
146 catch ( Exception e )
147 {
148 log.warn( "Exception while updating local OBR: " + e.getLocalizedMessage(), e );
149 }
150 }
151
152
153 protected void doTemplate( URI root, File path, ResourceImpl resource ) throws IOException, URISyntaxException
154 {
155 path = path.getAbsoluteFile().getCanonicalFile();
156 String finalUri = root.relativize( path.toURI() ).toString();
157 if ( "maven".equals( urlTemplate ) )
158 {
159 String dir = root.relativize( path.toURI() ).toString();
160 String[] p = dir.split( "/" );
161 if ( p.length >= 4 && p[p.length - 1].startsWith( p[p.length - 3] + "-" + p[p.length - 2] ) )
162 {
163 String artifactId = p[p.length - 3];
164 String version = p[p.length - 2];
165 String classifier;
166 String type;
167 String artifactIdVersion = artifactId + "-" + version;
168 StringBuffer sb = new StringBuffer();
169 if ( p[p.length - 1].charAt( artifactIdVersion.length() ) == '-' )
170 {
171 classifier = p[p.length - 1].substring( artifactIdVersion.length() + 1,
172 p[p.length - 1].lastIndexOf( '.' ) );
173 }
174 else
175 {
176 classifier = null;
177 }
178 type = p[p.length - 1].substring( p[p.length - 1].lastIndexOf( '.' ) + 1 );
179 sb.append( "mvn:" );
180 for ( int j = 0; j < p.length - 3; j++ )
181 {
182 if ( j > 0 )
183 {
184 sb.append( '.' );
185 }
186 sb.append( p[j] );
187 }
188 sb.append( '/' ).append( artifactId ).append( '/' ).append( version );
189 if ( !"jar".equals( type ) || classifier != null )
190 {
191 sb.append( '/' );
192 if ( !"jar".equals( type ) )
193 {
194 sb.append( type );
195 }
196 if ( classifier != null )
197 {
198 sb.append( '/' ).append( classifier );
199 }
200 }
201 finalUri = sb.toString();
202 }
203 }
204 else if ( urlTemplate != null )
205 {
206 URI parentDir = path.getParentFile().toURI();
207
208 String absoluteDir = trim( root.toString(), parentDir.toURL().toString() );
209 String relativeDir = trim( root.toString(), root.relativize( parentDir ).toString() );
210
211 String url = urlTemplate.replaceAll( "%v", "" + resource.getVersion() );
212 url = url.replaceAll( "%s", resource.getSymbolicName() );
213 url = url.replaceAll( "%f", path.getName() );
214 url = url.replaceAll( "%p", absoluteDir );
215 url = url.replaceAll( "%rp", relativeDir );
216 finalUri = url;
217 }
218 resource.put( Resource.URI, finalUri, Property.URI );
219 }
220
221
222 private String trim( String prefix, String path )
223 {
224 if ( path.endsWith( "/" ) )
225 path = path.substring( 0, path.length() - 1 );
226
227 if ( path.startsWith( prefix ) )
228 path = path.substring( prefix.length() );
229
230 return path;
231 }
232
233
234 private final FileFilter filter = new FileFilter()
235 {
236 public boolean accept( File pathname )
237 {
238 return pathname.getName().endsWith( "ar" );
239 }
240 };
241
242
243 private void findAllJars( File mainRoot, List<File> files )
244 {
245 List<File> roots = new ArrayList<File>();
246 roots.add( mainRoot );
247 while ( !roots.isEmpty() )
248 {
249 File root = roots.remove( 0 );
250 File[] children = root.listFiles();
251 if ( children != null )
252 {
253 for ( File child : children )
254 {
255 if ( child.isFile() && filter.accept( child ) )
256 {
257 files.add( child );
258 }
259 else if ( child.isDirectory() )
260 {
261 roots.add( child );
262 }
263 }
264 }
265 }
266 }
267
268 }