/* * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * Nuxeo - initial API and implementation * * $Id$ */ package org.nuxeo.osgi.application; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.jar.JarFile; import java.util.jar.Manifest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.nuxeo.common.utils.FileNamePattern; import org.nuxeo.common.utils.JarUtils; import org.nuxeo.osgi.BundleFile; import org.nuxeo.osgi.DirectoryBundleFile; import org.nuxeo.osgi.JarBundleFile; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; /** * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a> */ public class BundleWalker extends FileWalker.Visitor { private static final Log log = LogFactory.getLog(BundleWalker.class); public static final FileNamePattern[] DEFAULT_PATTERNS = { new FileNamePattern("*.jar"), new FileNamePattern("*.war"), new FileNamePattern("*.rar"), new FileNamePattern("*.sar"), // jboss sar new FileNamePattern("*_jar"), new FileNamePattern("*_war"), new FileNamePattern("*_rar") }; private FileNamePattern[] patterns; private final Callback callback; public BundleWalker(Callback cb) { this(cb, DEFAULT_PATTERNS); } public BundleWalker(Callback cb, String[] patterns) { if (patterns != null) { this.patterns = new FileNamePattern[patterns.length]; for (int i = 0; i < patterns.length; i++) { this.patterns[i] = new FileNamePattern(patterns[i]); } } callback = cb; } public BundleWalker(Callback cb, FileNamePattern[] patterns) { this.patterns = patterns; callback = cb; } public void visit(File root) { new FileWalker().walk(root, this); } public void visit(Collection<File> files) { for (File file : files) { if (file.isFile()) { if (file.isFile()) { visitFile(file); } else if (file.isDirectory()) { visitDirectory(file); } } } } public void visit(File... files) { for (File file : files) { if (file.isFile()) { if (file.isFile()) { visitFile(file); } else if (file.isDirectory()) { visitDirectory(file); } } } } @Override public int visitDirectory(File file) { // System.out.println("###### Processing DIR: " + file); // first check if this is a possible bundle String fileName = file.getName(); if (patterns != null) { if (!acceptFile(fileName, patterns)) { return FileWalker.CONTINUE; } } // check if this is an OSGi bundle try { Manifest mf = JarUtils.getDirectoryManifest(file); if (mf == null) { return FileWalker.CONTINUE; } String bundleName = mf.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME); if (bundleName != null) { // notify the callback about the new bundle callback.visitBundle(new DirectoryBundleFile(file, mf)); // assume that a directory OSGi bundle cannot contain other bundles so skip it return FileWalker.BREAK; } } catch (IOException e) { log.error(e, e); } return FileWalker.CONTINUE; } @Override public int visitFile(File file) { // System.out.println("###### Processing file: "+file); // first check if this is a possible bundle String fileName = file.getName(); if (patterns != null) { if (!acceptFile(fileName, patterns)) { // System.out.println("###### Ignoring file based on name: "+file); return FileWalker.CONTINUE; } } // check if this is an OSGi bundle try { JarFile jarFile = new JarFile(file); if (jarFile.getManifest() == null) { // System.out.println("###### No manifest found: "+file); return FileWalker.CONTINUE; } BundleFile bundleFile = new JarBundleFile(jarFile); if (bundleFile.getSymbolicName() != null) { // System.out.println("###### Bundle symbolic name: "+bundleFile.getSymbolicName()); // notify the callback about the new bundle callback.visitBundle(bundleFile); } else { // notify the callback about the new jar callback.visitJar(bundleFile); } } catch (IOException e) { // ignore } return FileWalker.CONTINUE; } protected boolean acceptFile(String fileName, FileNamePattern[] patterns) { int i = 0; for (; i < patterns.length; i++) { if (patterns[i].match(fileName)) { break; } } return i < patterns.length; } public interface Callback { void visitBundle(BundleFile bundleFile) throws IOException; void visitJar(BundleFile bundleFile) throws IOException; } }