APIRegistry.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
eclipseme.core.model |
![]() |
![]() |
EclipseME |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/**
* Copyright (c) 2007 Craig Setera
* All Rights Reserved.
* Licensed under the Eclipse Public License - v 1.0
* For more information see http://www.eclipse.org/legal/epl-v10.html
*/
package eclipseme.core.model;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import eclipseme.core.internal.EclipseMECorePlugin;
/**
* Provides access to the API definitions that have been registered via
* the API extension point.
* <p />
* Copyright (c) 2007 Craig Setera<br>
* All Rights Reserved.<br>
* Licensed under the Eclipse Public License - v 1.0<p/>
* <br>
* $Revision$
* <br>
* $Date$
* <br>
* @author Craig Setera
*/
/**
* @author setera
*
*/
public class APIRegistry {
private static final String ATTR_VERSION = "API-Specification-Version";
private static final String ATTR_IDENTIFIER = "API";
private static final String ATTR_NAME = "API-Name";
private static final String ATTR_TYPE = "API-Type";
private static final String ATTR_TYPE_PROFILE = "Profile";
private static final String ATTR_TYPE_CONFIGURATION = "Configuration";
private static final String ATTR_TYPE_OPTIONAL = "Optional";
// The extension point
private static final String EXT_API = "api";
// The API definitions ordered as they are found in the registry
private static List orderedApis;
// The API definitions keyed by their identifier
private static Map apisByIdentifier;
/**
* Return the {@link API} instances in the order that they were
* found within the registry.
*
* @return
* @throws IOException
*/
public static List getAPIDefinitions()
throws IOException
{
if (orderedApis == null) {
orderedApis = readAPIDefinitions();
}
return orderedApis;
}
/**
* Return the API with the specified identifier and version.
*
* @param identifier
* @param version
* @return
*/
public static API getAPI(String identifier, Version version) {
API api = null;
try {
Map byId = getAPIsByIdentifier();
List apiList = (List) byId.get(identifier);
Iterator iterator = apiList.iterator();
while (iterator.hasNext()) {
API apiTemp = (API) iterator.next();
if (version.equals(apiTemp.getVersion())) {
api = apiTemp;
break;
}
}
} catch (IOException e) {
EclipseMECorePlugin.log(IStatus.WARNING, e);
}
return api;
}
/**
* Return the list of API's present in specified JAR file.
*
* @param jarFile
* @return
* @throws IOException
*/
public static API[] getAPIs(File jarFile) {
Map apis = new HashMap();
JarFile jar = null;
try {
jar = new JarFile(jarFile);
if (jar != null) {
addRegisteredAPIs(apis, jar);
if (apis.size() == 0) {
// We failed to match anything registered, so create a new
// definition
API api = createAPIFromManifest(jar);
if (api != null) {
apis.put(api.getIdentifier(), api);
}
}
}
} catch (IOException e) {
} finally {
if (jar != null) {
try { jar.close(); } catch (IOException e) {}
}
}
// Final fallback position
if (apis.size() == 0) {
API unknown = createUnknownAPI(jarFile);
apis.put(unknown.getIdentifier(), unknown);
}
// Convert to the final array
Collection values = apis.values();
return (API[]) values.toArray(new API[values.size()]);
}
/**
* Add all registered APIs that match the jar file by primary
* class or identifier.
*
* @param apis
* @param jar
* @throws IOException
*/
private static void addRegisteredAPIs(Map apis, JarFile jar)
throws IOException
{
String jarApiIdentifier = "";
Manifest manifest = jar.getManifest();
if (manifest != null) {
Attributes attributes = manifest.getMainAttributes();
jarApiIdentifier = attributes.getValue(ATTR_IDENTIFIER);
}
if (jarApiIdentifier != null) {
Iterator apiIter = getAPIDefinitions().iterator();
while (apiIter.hasNext()) {
API api = (API) apiIter.next();
// Try to match based on the classes in the jar file
String primaryClass = api.getPrimaryMatchableClass();
if (primaryClass != null) {
primaryClass = primaryClass.replace('.', '/') + ".class";
if (jar.getEntry(primaryClass) != null) {
addVersionFilteredAPI(apis, api);
}
}
// Also look at a match based on API identifier
if (jarApiIdentifier.equals(api.getIdentifier())) {
addVersionFilteredAPI(apis, api);
}
}
}
}
/**
* Add the specified API into the map of API's appropriately handling
* versioning. When done, we should only have a single API for each
* identifier and it should be the greatest version number match.
*
* @param apis
* @param api
*/
private static void addVersionFilteredAPI(Map apis, API api) {
API currentAPI = (API) apis.get(api.getIdentifier());
if (currentAPI != null) {
// We already have this API in our list. If the version
// being added is a higher version, replace the current.
if (api.getVersion().compareTo(currentAPI.getVersion()) > 0) {
apis.put(api.getIdentifier(), api);
}
} else {
// Let's handle MIDP/IMP as a special-case here...
if (api.getIdentifier().equals("IMP")) {
if (apis.get("MIDP") == null) {
// Go ahead and add this...
apis.put(api.getIdentifier(), api);
}
} else if (api.getIdentifier().equals("MIDP")) {
if (apis.get("IMP") != null) {
apis.remove("IMP");
}
apis.put(api.getIdentifier(), api);
} else {
apis.put(api.getIdentifier(), api);
}
}
}
/**
* Attempt to return an API definition for the information
* in the manifest.
*
* @param attributes
* @return
* @throws IOException
*/
private static API createAPIFromManifest(JarFile jarFile)
throws IOException
{
API api = null;
Manifest manifest = jarFile.getManifest();
if (manifest != null) {
Attributes attributes = manifest.getMainAttributes();
String identifier = attributes.getValue(ATTR_IDENTIFIER);
if (identifier != null) {
api = new API();
api.setIdentifier(identifier);
api.setName(attributes.getValue(ATTR_NAME));
api.setType(getTypeFromManifest(attributes));
api.setVersion(getVersionFromManifest(attributes));
}
}
return api;
}
/**
* Return a new unknown API instance.
*
* @param libraryFile
* @return
*/
private static API createUnknownAPI(File libraryFile) {
API api = new API();
api.setIdentifier(libraryFile.getName());
api.setName("Unknown Library");
api.setType(APIType.UNKNOWN);
api.setVersion(new Version("1.0"));
return api;
}
/**
* Return the API's keyed by identifier.
*
* @return
* @throws IOException
*/
private static Map getAPIsByIdentifier()
throws IOException
{
if (apisByIdentifier == null) {
apisByIdentifier = new HashMap();
Iterator iterator = getAPIDefinitions().iterator();
while (iterator.hasNext()) {
API api = (API) iterator.next();
List apis = (List) apisByIdentifier.get(api.getIdentifier());
if (apis == null) {
apis = new ArrayList();
apisByIdentifier.put(api.getIdentifier(), apis);
}
apis.add(api);
}
}
return apisByIdentifier;
}
/**
* Return the integer type of the value specified
* in the manifest.
*
* @param attributes
* @return
*/
private static APIType getTypeFromManifest(Attributes attributes) {
APIType type = APIType.UNKNOWN;
String typeString = attributes.getValue(ATTR_TYPE);
if (typeString.equalsIgnoreCase(ATTR_TYPE_OPTIONAL)) {
type = APIType.OPTIONAL;
} else if (typeString.equalsIgnoreCase(ATTR_TYPE_PROFILE)) {
type = APIType.PROFILE;
} else if (typeString.equalsIgnoreCase(ATTR_TYPE_CONFIGURATION)) {
type = APIType.CONFIGURATION;
}
return type;
}
/**
* Return the version of the API as found in the
* attributes.
*
* @param attributes
* @return
*/
private static Version getVersionFromManifest(Attributes attributes) {
Version version = null;
String versionString = attributes.getValue(ATTR_VERSION);
if (versionString != null) {
version = new Version(versionString);
} else {
version = new Version("0.0.0");
}
return version;
}
/**
* Read in the API definitions from the registry.
*
* @return
* @throws IOException
*/
private static List readAPIDefinitions()
throws IOException
{
List apis = new ArrayList();
String pluginId = EclipseMECorePlugin.getDefault().getBundle().getSymbolicName();
IExtensionRegistry registry = Platform.getExtensionRegistry();
IConfigurationElement[] elements =
registry.getConfigurationElementsFor(pluginId, EXT_API);
for (int i = 0; i < elements.length; i++) {
apis.add(new API(elements[i]));
}
return Collections.unmodifiableList(apis);
}
// Private constructor for static access.
private APIRegistry() {}
}
The table below shows all metrics for APIRegistry.java.




