package org.bundlemaker.core.common.internal.fileinfo; import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.osgi.framework.Constants; /** * <p> * </p> * * @author Gerd Wütherich (gerd@gerd-wuetherich.de) */ public class DefaultFileBasedContentInfoResolver implements IFileBasedProjectContentInfoResolver { /** * The pattern to identify source module names and extract it's associated binary names if possible */ final static Pattern _pattern = Pattern.compile("(.*)[\\._-](src|source|sources)[-_]?.*"); /** - */ private String _name; /** - */ private String _version; /** - */ private boolean _isSource; /** - */ private JarFile _jarFile; /** - */ private Manifest _manifest; /** - */ private File _file; private String _binaryName; /** * {@inheritDoc} */ @Override public boolean resolve(File file) { // try { // _file = file; _jarFile = new JarFile(file); _manifest = _jarFile.getManifest(); // _name = extractName(); if (_name == null) { return false; } _binaryName = extractAssociatedBinaryName(_name); _version = extractVersion(); if (_version == null) { return false; } // _isSource = extractIsSource(); // return true; } // catch (IOException e) { return false; } } /** * @param name * @return */ public static String extractAssociatedBinaryName(String name) { Matcher matcher = _pattern.matcher(name); if (!matcher.matches() || matcher.groupCount() != 2) { // cannot determine... return name; } return matcher.group(1); } /** * {@inheritDoc} */ @Override public String getName() { return _name; } public String getBinaryName() { return _binaryName; } /** * {@inheritDoc} */ @Override public String getVersion() { return _version; } /** * {@inheritDoc} */ @Override public boolean isSource() { return _isSource; } /** * Returns true if the given value matches the source name pattern * * @param value * @return */ public static boolean isSourcePattern(String value) { Matcher matcher = _pattern.matcher(value); boolean result = matcher.matches(); return result; } /** * <p> * </p> * * @return */ private boolean extractIsSource() { return isSourcePattern(_file.getName()); } /** * <p> * </p> * * @return * @throws IOException */ private String extractName() throws IOException { // String result = null; // step 1: check if a symbolic name exists if (_manifest != null) { result = _manifest.getMainAttributes().getValue(Constants.BUNDLE_SYMBOLICNAME); if (result != null) { int end = result.indexOf(';'); if (end > 0) { result = result.substring(0, end); } return result; } } // try to read maven properties Enumeration<JarEntry> entries = _jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = (JarEntry) entries.nextElement(); if (jarEntry.getName().endsWith("pom.properties")) { Properties properties = new Properties(); properties.load(_jarFile.getInputStream(jarEntry)); // version=0.9.26 // groupId=ch.qos.logback // artifactId=logback-core return properties.getProperty("groupId") + "." + properties.getProperty("artifactId"); } } // step 2: result = LogicalJarNameResolver.extractName(_file.getName()); if (result != null) { return result; } // step 3: result = LogicalJarNameResolver.extractNameFromRootDirectory(_jarFile); if (result != null) { return result; } // step 4: if (_manifest != null) { // try to extract the name from the main class attribute result = LogicalJarNameResolver.extractNameFromMainClassAttribute(_manifest); if (result != null) { return result; } // try to extract the name from the implementation title // attribute result = LogicalJarNameResolver.extractNameFromImplementationTitle(_manifest); if (result != null) { return result; } } // return result; } /** * <p> * </p> * * @param file * @return * @throws IOException */ private String extractVersion() throws IOException { String version = null; // Try to analyze the manifest file // get the manifest file Manifest manifest = _jarFile.getManifest(); if (manifest != null) { // Try Bundle-Version version = LogicalJarVersionResolver.extractNameFromBundleVersion(manifest); // Try Implementation-Version if (version == null) { version = LogicalJarVersionResolver.extractNameFromImplementationVersion(manifest); } // Try Specification if (version == null) { version = LogicalJarVersionResolver.extractNameFromSpecificationVersion(manifest); } } // Still no version found, try maven pom properties if (version == null) { // try to read maven pom.properties Enumeration<JarEntry> entries = _jarFile.entries(); while (entries.hasMoreElements()) { JarEntry jarEntry = (JarEntry) entries.nextElement(); if (jarEntry.getName().endsWith("pom.properties")) { Properties properties = new Properties(); properties.load(_jarFile.getInputStream(jarEntry)); version = properties.getProperty("version"); break; } } } File fileToParse = _file; while (version == null && fileToParse != null) { version = LogicalJarVersionResolver.extractVersionFromName(fileToParse.getName()); if (version == null) { fileToParse = fileToParse.getParentFile(); } } // Determine from Filename return (version == null ? "0.0.0" : version); } }