01: /*
02: * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
03: * notice. All rights reserved.
04: */
05: package com.tc.bundles;
06:
07: import java.util.ArrayList;
08: import java.util.List;
09: import java.util.jar.Manifest;
10: import java.util.regex.Matcher;
11: import java.util.regex.Pattern;
12: import java.lang.reflect.Constructor;
13: import java.text.MessageFormat;
14:
15: public abstract class BundleSpec {
16:
17: private static final String REQUIRE_BUNDLE = "Require-Bundle";
18: protected static final String PROP_KEY_RESOLUTION = "resolution";
19: protected static final String PROP_KEY_BUNDLE_VERSION = "bundle-version";
20: protected static final String BUNDLE_SYMBOLIC_NAME_REGEX = "[a-zA-Z][A-Za-z0-9._\\-]+";
21: protected static final String REQUIRE_BUNDLE_EXPR_MATCHER = "("
22: + BUNDLE_SYMBOLIC_NAME_REGEX
23: + "(;resolution:=\"?optional\"?)?" + //
24: "(;bundle-version:=(\"?[A-Za-z0-9.]+\"?|" + //
25: "\"?[\\[\\(][A-Za-z0-9.]+,[A-Za-z0-9.]*[\\]\\)]\"?))?)";
26:
27: public abstract String getSymbolicName();
28:
29: public abstract String getName();
30:
31: public abstract String getGroupId();
32:
33: public abstract String getVersion();
34:
35: public abstract boolean isOptional();
36:
37: public abstract boolean isCompatible(final String symname,
38: final String version);
39:
40: public final static boolean isMatchingSymbolicName(
41: final String arg0, final String arg1) {
42: return (arg0 != null)
43: && (arg1 != null)
44: && arg0.replace('-', '_').equalsIgnoreCase(
45: arg1.replace('-', '_'));
46: }
47:
48: public static final String[] getRequirements(final Manifest manifest) {
49: return getRequirements(manifest.getMainAttributes().getValue(
50: REQUIRE_BUNDLE));
51: }
52:
53: public static final String[] getRequirements(
54: final String requiredBundles) {
55: if (requiredBundles == null)
56: return new String[0];
57:
58: final List list = new ArrayList();
59: final String spec = requiredBundles.replaceAll(" ", "");
60: final Pattern pattern = Pattern
61: .compile(REQUIRE_BUNDLE_EXPR_MATCHER);
62: final Matcher matcher = pattern.matcher(spec);
63: final StringBuffer check = new StringBuffer();
64:
65: while (matcher.find()) {
66: final String group = matcher.group();
67: check.append("," + group);
68: list.add(group);
69: }
70:
71: if (!spec.equals(check.toString().replaceFirst(",", ""))) {
72: final String arg0 = "Syntax error specifying the required bundle list in the manifest: ''{0}'' found ''{1}''";
73: final Object[] arg1 = { requiredBundles, check };
74: throw new RuntimeException(MessageFormat.format(arg0, arg1));
75: }
76:
77: return (String[]) list.toArray(new String[list.size()]);
78: }
79:
80: public static final BundleSpec newInstance(final String spec) {
81: final String BUNDLESPECIMPL = "com.tc.bundles.BundleSpecImpl";
82: try {
83: final Class klass = Class.forName(BUNDLESPECIMPL);
84: final Constructor constructor = klass
85: .getDeclaredConstructor(new Class[] { String.class });
86: return (BundleSpec) constructor
87: .newInstance(new Object[] { spec });
88: } catch (Exception e) {
89: throw new RuntimeException(
90: "Unable to create an instance of class "
91: + BUNDLESPECIMPL, e);
92: }
93: }
94: }
|