一、前言
基于abdera-bundle的org.apache.abdera.util.ServiceUtil工具类实现对系统常用的开发接口注入默认的实现类,最好统一将所有系统实例注入到核心类Abdera,提供统一的实例化接口,这个好比spring bean实例化工厂。
二、源码
1.核心代码类org.apache.abdera.Abdera
package org.apache.abdera;@b@@b@import org.apache.abdera.factory.Factory;@b@import org.apache.abdera.i18n.iri.IRI;@b@import org.apache.abdera.model.Categories;@b@import org.apache.abdera.model.Entry;@b@import org.apache.abdera.model.Feed;@b@import org.apache.abdera.model.Service;@b@import org.apache.abdera.parser.Parser;@b@import org.apache.abdera.parser.ParserFactory;@b@import org.apache.abdera.util.AbderaConfiguration;@b@import org.apache.abdera.util.Configuration;@b@import org.apache.abdera.writer.StreamWriter;@b@import org.apache.abdera.writer.Writer;@b@import org.apache.abdera.writer.WriterFactory;@b@import org.apache.abdera.xpath.XPath;@b@@b@public class Abdera@b@{@b@ private static Abdera instance;@b@ private final Configuration config;@b@ private final Factory factory;@b@ private final Parser parser;@b@ private final XPath xpath;@b@ private final ParserFactory parserFactory;@b@ private final WriterFactory writerFactory;@b@ private final Writer writer;@b@@b@ public static synchronized Abdera getInstance()@b@ {@b@ if (instance == null) instance = new Abdera();@b@ return instance;@b@ }@b@@b@ public Abdera()@b@ {@b@ this(AbderaConfiguration.getDefault());@b@ }@b@@b@ public Abdera(Configuration config)@b@ {@b@ this.config = config;@b@ this.factory = newFactory();@b@ this.parser = newParser();@b@ this.xpath = newXPath();@b@ this.parserFactory = newParserFactory();@b@ this.writerFactory = newWriterFactory();@b@ this.writer = newWriter();@b@ IRI.preinit();@b@ }@b@@b@ public Feed newFeed()@b@ {@b@ return getFactory().newFeed();@b@ }@b@@b@ public Entry newEntry()@b@ {@b@ return getFactory().newEntry();@b@ }@b@@b@ public Service newService()@b@ {@b@ return getFactory().newService();@b@ }@b@@b@ public Categories newCategories()@b@ {@b@ return getFactory().newCategories();@b@ }@b@@b@ public Configuration getConfiguration()@b@ {@b@ return this.config;@b@ }@b@@b@ public Factory getFactory()@b@ {@b@ return this.factory;@b@ }@b@@b@ public Parser getParser()@b@ {@b@ return this.parser;@b@ }@b@@b@ public XPath getXPath()@b@ {@b@ return this.xpath;@b@ }@b@@b@ public ParserFactory getParserFactory()@b@ {@b@ return this.parserFactory;@b@ }@b@@b@ public WriterFactory getWriterFactory()@b@ {@b@ return this.writerFactory;@b@ }@b@@b@ public Writer getWriter()@b@ {@b@ return this.writer;@b@ }@b@@b@ private Factory newFactory()@b@ {@b@ return this.config.newFactoryInstance(this);@b@ }@b@@b@ private Parser newParser()@b@ {@b@ return this.config.newParserInstance(this);@b@ }@b@@b@ private XPath newXPath()@b@ {@b@ return this.config.newXPathInstance(this);@b@ }@b@@b@ private ParserFactory newParserFactory()@b@ {@b@ return this.config.newParserFactoryInstance(this);@b@ }@b@@b@ private WriterFactory newWriterFactory()@b@ {@b@ return this.config.newWriterFactoryInstance(this);@b@ }@b@@b@ private Writer newWriter()@b@ {@b@ return this.config.newWriterInstance(this);@b@ }@b@@b@ public StreamWriter newStreamWriter()@b@ {@b@ return this.config.newStreamWriterInstance(this);@b@ }@b@@b@ public static Factory getNewFactory()@b@ {@b@ return new Abdera().newFactory();@b@ }@b@@b@ public static Parser getNewParser()@b@ {@b@ return new Abdera().newParser();@b@ }@b@@b@ public static XPath getNewXPath()@b@ {@b@ return new Abdera().newXPath();@b@ }@b@@b@ public static ParserFactory getNewParserFactory()@b@ {@b@ return new Abdera().newParserFactory();@b@ }@b@@b@ public static WriterFactory getNewWriterFactory()@b@ {@b@ return new Abdera().newWriterFactory();@b@ }@b@@b@ public static Writer getNewWriter()@b@ {@b@ return new Abdera().newWriter();@b@ }@b@@b@ public static StreamWriter getNewStreamWriter()@b@ {@b@ return new Abdera().newStreamWriter();@b@ }@b@}
2.核心配置类AbderaConfiguration
package org.apache.abdera.util;@b@@b@import java.lang.reflect.Field;@b@import java.lang.reflect.Modifier;@b@import java.util.Collections;@b@import java.util.HashMap;@b@import java.util.List;@b@import java.util.Locale;@b@import java.util.Map;@b@import java.util.ResourceBundle;@b@import org.apache.abdera.Abdera;@b@import org.apache.abdera.factory.ExtensionFactory;@b@import org.apache.abdera.factory.Factory;@b@import org.apache.abdera.factory.StreamBuilder;@b@import org.apache.abdera.i18n.text.Localizer;@b@import org.apache.abdera.parser.NamedParser;@b@import org.apache.abdera.parser.Parser;@b@import org.apache.abdera.parser.ParserFactory;@b@import org.apache.abdera.writer.NamedWriter;@b@import org.apache.abdera.writer.StreamWriter;@b@import org.apache.abdera.writer.Writer;@b@import org.apache.abdera.writer.WriterFactory;@b@import org.apache.abdera.xpath.XPath;@b@@b@public final class AbderaConfiguration@b@ implements Constants, Configuration@b@{@b@ private static final long serialVersionUID = 7460203853824337559L;@b@ private final ResourceBundle bundle;@b@ private final List<ExtensionFactory> factories;@b@ private final Map<String, NamedWriter> writers;@b@ private final Map<String, Class<? extends StreamWriter>> streamwriters;@b@ private final Map<String, NamedParser> parsers;@b@@b@ public static synchronized Configuration getDefault()@b@ {@b@ Configuration instance = null;@b@ try {@b@ ResourceBundle bundle = ResourceBundle.getBundle("abdera");@b@ instance = new AbderaConfiguration(bundle);@b@ } catch (Exception e) {@b@ instance = new AbderaConfiguration();@b@ }@b@ return instance;@b@ }@b@@b@ private static ResourceBundle getBundle(ClassLoader loader, Locale locale)@b@ {@b@ ResourceBundle bundle = null;@b@ try {@b@ bundle = ResourceBundle.getBundle("abdera", locale, loader);@b@ }@b@ catch (Exception e)@b@ {@b@ }@b@@b@ return bundle;@b@ }@b@@b@ public AbderaConfiguration()@b@ {@b@ this(null);@b@ }@b@@b@ protected AbderaConfiguration(ResourceBundle bundle) {@b@ this.bundle = ((bundle != null) ? bundle : getBundle(ServiceUtil.getClassLoader(), Locale.getDefault()));@b@@b@ this.factories = ServiceUtil.loadExtensionFactories();@b@ this.writers = initNamedWriters();@b@ this.parsers = initNamedParsers();@b@ this.streamwriters = initStreamWriters();@b@ }@b@@b@ private ResourceBundle getBundle() {@b@ return this.bundle;@b@ }@b@@b@ public String getConfigurationOption(String id)@b@ {@b@ String option = System.getProperty(id);@b@ if (option == null)@b@ try {@b@ ResourceBundle bundle = getBundle();@b@ if (bundle != null) option = bundle.getString(id);@b@ }@b@ catch (Exception e)@b@ {@b@ }@b@ return option;@b@ }@b@@b@ public String getConfigurationOption(String id, String _default)@b@ {@b@ String value = getConfigurationOption(id);@b@ return ((value != null) ? value : _default);@b@ }@b@@b@ public AbderaConfiguration addExtensionFactory(ExtensionFactory factory)@b@ {@b@ List factories = getExtensionFactories();@b@ if (!(factories.contains(factory)))@b@ factories.add(factory);@b@ return this;@b@ }@b@@b@ public List<ExtensionFactory> getExtensionFactories()@b@ {@b@ return this.factories;@b@ }@b@@b@ public AbderaConfiguration addNamedWriter(NamedWriter writer)@b@ {@b@ Map writers = getNamedWriters();@b@ writers.put(writer.getName(), writer);@b@ return this;@b@ }@b@@b@ private Map<String, NamedWriter> initNamedWriters()@b@ {@b@ Map writers = null;@b@ List _writers = ServiceUtil._loadimpls("META-INF/services/org.apache.abdera.writer.NamedWriter");@b@@b@ writers = Collections.synchronizedMap(new HashMap());@b@ for (NamedWriter writer : _writers)@b@ writers.put(writer.getName().toLowerCase(), writer);@b@@b@ return writers;@b@ }@b@@b@ private Map<String, Class<? extends StreamWriter>> initStreamWriters()@b@ {@b@ Map writers = null;@b@ List _writers = ServiceUtil._loadimpls("META-INF/services/org.apache.abdera.writer.StreamWriter", true);@b@@b@ writers = Collections.synchronizedMap(new HashMap());@b@ for (Class writer : _writers) {@b@ String name = getName(writer);@b@ if (name != null)@b@ writers.put(name.toLowerCase(), writer);@b@ }@b@ writers.put("fom", StreamBuilder.class);@b@ return writers;@b@ }@b@@b@ private static String getName(Class<? extends StreamWriter> sw) {@b@ String name = null;@b@ try {@b@ Field field = sw.getField("NAME");@b@ if (Modifier.isStatic(field.getModifiers()))@b@ name = (String)field.get(null);@b@ } catch (Exception e) {@b@ }@b@ return name;@b@ }@b@@b@ public Map<String, NamedWriter> getNamedWriters()@b@ {@b@ return this.writers;@b@ }@b@@b@ public Map<String, Class<? extends StreamWriter>> getStreamWriters()@b@ {@b@ return this.streamwriters;@b@ }@b@@b@ public AbderaConfiguration addNamedParser(NamedParser parser)@b@ {@b@ Map parsers = getNamedParsers();@b@ parsers.put(parser.getName(), parser);@b@ return this;@b@ }@b@@b@ public AbderaConfiguration addStreamWriter(Class<? extends StreamWriter> sw)@b@ {@b@ getStreamWriters().put(getName(sw), sw);@b@ return this;@b@ }@b@@b@ private Map<String, NamedParser> initNamedParsers()@b@ {@b@ Map parsers = null;@b@ List _parsers = ServiceUtil._loadimpls("META-INF/services/org.apache.abdera.parser.NamedParser");@b@ parsers = Collections.synchronizedMap(new HashMap());@b@ for (NamedParser parser : _parsers)@b@ parsers.put(parser.getName().toLowerCase(), parser);@b@@b@ return parsers;@b@ }@b@@b@ public Map<String, NamedParser> getNamedParsers()@b@ {@b@ return this.parsers;@b@ }@b@@b@ public Object clone() {@b@ try {@b@ return super.clone();@b@ } catch (CloneNotSupportedException e) {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ public Factory newFactoryInstance(Abdera abdera)@b@ {@b@ return ServiceUtil.newFactoryInstance(abdera);@b@ }@b@@b@ public Parser newParserInstance(Abdera abdera)@b@ {@b@ return ServiceUtil.newParserInstance(abdera);@b@ }@b@@b@ public XPath newXPathInstance(Abdera abdera)@b@ {@b@ try@b@ {@b@ return ServiceUtil.newXPathInstance(abdera);@b@ } catch (NoClassDefFoundError n) {@b@ throw new RuntimeException(Localizer.sprintf("IMPLEMENTATION.NOT.AVAILABLE", new Object[] { "XPath" }), n);@b@ }@b@ }@b@@b@ public ParserFactory newParserFactoryInstance(Abdera abdera)@b@ {@b@ try@b@ {@b@ return ServiceUtil.newParserFactoryInstance(abdera);@b@ } catch (NoClassDefFoundError n) {@b@ throw new RuntimeException(Localizer.sprintf("IMPLEMENTATION.NOT.AVAILABLE", new Object[] { "Parser" }), n);@b@ }@b@ }@b@@b@ public WriterFactory newWriterFactoryInstance(Abdera abdera)@b@ {@b@ try@b@ {@b@ return ServiceUtil.newWriterFactoryInstance(abdera);@b@ } catch (NoClassDefFoundError n) {@b@ throw new RuntimeException(Localizer.sprintf("IMPLEMENTATION.NOT.AVAILABLE", new Object[] { "WriterFactory" }), n);@b@ }@b@ }@b@@b@ public Writer newWriterInstance(Abdera abdera)@b@ {@b@ try@b@ {@b@ return ServiceUtil.newWriterInstance(abdera);@b@ } catch (NoClassDefFoundError n) {@b@ throw new RuntimeException(Localizer.sprintf("IMPLEMENTATION.NOT.AVAILABLE", new Object[] { "Writer" }), n);@b@ }@b@ }@b@@b@ public StreamWriter newStreamWriterInstance(Abdera abdera)@b@ {@b@ try@b@ {@b@ return ServiceUtil.newStreamWriterInstance(abdera);@b@ } catch (NoClassDefFoundError n) {@b@ throw new RuntimeException(Localizer.sprintf("IMPLEMENTATION.NOT.AVAILABLE", new Object[] { "StreamWriter" }), n);@b@ }@b@ }@b@}
3.默认服务注册工具类ServiceUtil
package org.apache.abdera.util;@b@@b@import java.io.BufferedReader;@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.io.InputStreamReader;@b@import java.lang.reflect.Constructor;@b@import java.net.URL;@b@import java.util.ArrayList;@b@import java.util.Collections;@b@import java.util.Enumeration;@b@import java.util.List;@b@import org.apache.abdera.Abdera;@b@import org.apache.abdera.factory.ExtensionFactory;@b@import org.apache.abdera.factory.Factory;@b@import org.apache.abdera.parser.Parser;@b@import org.apache.abdera.parser.ParserFactory;@b@import org.apache.abdera.writer.StreamWriter;@b@import org.apache.abdera.writer.Writer;@b@import org.apache.abdera.writer.WriterFactory;@b@import org.apache.abdera.xpath.XPath;@b@@b@public final class ServiceUtil@b@ implements Constants@b@{@b@ public static Object newInstance(String id, String _default, Abdera abdera)@b@ {@b@ return locate(id, _default, abdera);@b@ }@b@@b@ public static Object newInstance(String id, String _default, Abdera abdera, Object[] args)@b@ {@b@ return locate(id, _default, abdera, args);@b@ }@b@@b@ public static XPath newXPathInstance(Abdera abdera)@b@ {@b@ return ((XPath)newInstance("org.apache.abdera.xpath.XPath", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.xpath.XPath", "org.apache.abdera.parser.stax.FOMXPath"), abdera));@b@ }@b@@b@ public static Parser newParserInstance(Abdera abdera)@b@ {@b@ return ((Parser)newInstance("org.apache.abdera.parser.Parser", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.parser.Parser", "org.apache.abdera.parser.stax.FOMParser"), abdera));@b@ }@b@@b@ public static Factory newFactoryInstance(Abdera abdera)@b@ {@b@ return ((Factory)newInstance("org.apache.abdera.factory.Factory", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.factory.Factory", "org.apache.abdera.parser.stax.FOMFactory"), abdera));@b@ }@b@@b@ public static ParserFactory newParserFactoryInstance(Abdera abdera)@b@ {@b@ return ((ParserFactory)newInstance("org.apache.abdera.parser.ParserFactory", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.parser.ParserFactory", "org.apache.abdera.parser.stax.FOMParserFactory"), abdera));@b@ }@b@@b@ public static WriterFactory newWriterFactoryInstance(Abdera abdera)@b@ {@b@ return ((WriterFactory)newInstance("org.apache.abdera.writer.WriterFactory", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.writer.WriterFactory", "org.apache.abdera.parser.stax.FOMWriterFactory"), abdera));@b@ }@b@@b@ public static Writer newWriterInstance(Abdera abdera)@b@ {@b@ return ((Writer)newInstance("org.apache.abdera.writer.Writer", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.writer.Writer", "org.apache.abdera.parser.stax.FOMWriter"), abdera));@b@ }@b@@b@ public static StreamWriter newStreamWriterInstance(Abdera abdera)@b@ {@b@ return ((StreamWriter)newInstance("org.apache.abdera.writer.StreamWriter", abdera.getConfiguration().getConfigurationOption("org.apache.abdera.writer.StreamWriter", "org.apache.abdera.parser.stax.StaxStreamWriter"), abdera));@b@ }@b@@b@ public static ClassLoader getClassLoader()@b@ {@b@ return Thread.currentThread().getContextClassLoader();@b@ }@b@@b@ public static Object locate(String id, String _default, Abdera abdera)@b@ {@b@ Object object = locate(id, abdera);@b@ if ((object == null) && (_default != null))@b@ object = locateInstance(getClassLoader(), _default, abdera);@b@@b@ return object;@b@ }@b@@b@ public static Object locate(String id, String _default, Abdera abdera, Object[] args)@b@ {@b@ Object object = locate(id, abdera);@b@ if ((object == null) && (_default != null))@b@ object = locateInstance(getClassLoader(), _default, abdera, args);@b@@b@ return object;@b@ }@b@@b@ public static Object locate(String id, Abdera abdera)@b@ {@b@ Object service = checkAbderaConfiguration(id, abdera);@b@ return ((service != null) ? service : checkMetaInfServices(id, abdera));@b@ }@b@@b@ private static Object _create(Class _class, Abdera abdera)@b@ {@b@ if (_class == null) return null;@b@ try {@b@ if (abdera != null) {@b@ Constructor c = _class.getConstructor(new Class[] { Abdera.class });@b@ return c.newInstance(new Object[] { abdera });@b@ }@b@ }@b@ catch (Exception e) {@b@ }@b@ try {@b@ return _class.newInstance();@b@ }@b@ catch (Exception e) {@b@ }@b@ return null;@b@ }@b@@b@ private static Object _create(Class _class, Abdera abdera, Object[] args)@b@ {@b@ int n;@b@ Class[] types = null;@b@ Object[] values = null;@b@ if (_class == null) return null;@b@ try {@b@ if (abdera != null) {@b@ types = new Class[args.length + 1];@b@ values = new Object[args.length + 1];@b@ types[0] = Abdera.class;@b@ values[0] = abdera;@b@ for (n = 0; n < args.length; ++n) {@b@ types[(n + 1)] = args[n].getClass();@b@ values[(n + 1)] = args[n];@b@ }@b@ Constructor c = _class.getConstructor(types);@b@ return c.newInstance(values);@b@ }@b@ }@b@ catch (Exception e) {@b@ }@b@ try {@b@ types = new Class[args.length];@b@ for (e = 0; e < args.length; ++e)@b@ types[e] = args[e].getClass();@b@ return _class.getConstructor(types).newInstance(args);@b@ }@b@ catch (Exception e) {@b@ }@b@ return null;@b@ }@b@@b@ public static Object locateInstance(ClassLoader loader, String id, Abdera abdera) {@b@ return locateInstance(loader, id, abdera, false);@b@ }@b@@b@ public static Object locateInstance(ClassLoader loader, String id, Abdera abdera, boolean classesonly) {@b@ Class _class;@b@ try {@b@ _class = loader.loadClass(id);@b@ return ((classesonly) ? _class : _create(_class, abdera));@b@ }@b@ catch (Exception e)@b@ {@b@ try {@b@ e = ClassLoader.getSystemClassLoader().loadClass(id);@b@ return ((classesonly) ? e : _create(e, abdera));@b@ } catch (Exception e) {@b@ }@b@ }@b@ return null;@b@ }@b@@b@ public static Object locateInstance(ClassLoader loader, String id, Abdera abdera, Object[] args) {@b@ Class _class;@b@ try {@b@ _class = loader.loadClass(id);@b@ return _create(_class, abdera, args);@b@ }@b@ catch (Exception e)@b@ {@b@ try {@b@ e = ClassLoader.getSystemClassLoader().loadClass(id);@b@ return _create(e, abdera, args);@b@ } catch (Exception e) {@b@ }@b@ }@b@ return null;@b@ }@b@@b@ public static InputStream locateStream(ClassLoader loader, String id) {@b@ InputStream in = loader.getResourceAsStream(id);@b@ return ((in != null) ? in : ClassLoader.getSystemResourceAsStream(id));@b@ }@b@@b@ public static Enumeration<URL> locateResources(ClassLoader loader, String id) {@b@ try {@b@ return loader.getResources(id);@b@ }@b@ catch (Exception e)@b@ {@b@ try {@b@ return ClassLoader.getSystemResources(id);@b@ } catch (Exception e) {@b@ }@b@ }@b@ return null;@b@ }@b@@b@ private static Object checkAbderaConfiguration(String id, Abdera abdera)@b@ {@b@ String s = abdera.getConfiguration().getConfigurationOption(id);@b@ return ((s != null) ? locateInstance(getClassLoader(), id, abdera) : null);@b@ }@b@@b@ private static Object checkMetaInfServices(String id, Abdera abdera) {@b@ Object object = null;@b@ String sid = "META-INF/services/" + id;@b@ ClassLoader loader = getClassLoader();@b@ BufferedReader buf = null;@b@ try {@b@ InputStream is = locateStream(loader, sid);@b@ if (is != null) {@b@ buf = new BufferedReader(new InputStreamReader(is));@b@ String line = buf.readLine();@b@ if (line != null) {@b@ String s = line.split("#", 2)[0].trim();@b@ object = locateInstance(loader, s, abdera);@b@ }@b@ }@b@ } catch (Exception e) {@b@ }@b@ finally {@b@ if (buf != null)@b@ try {@b@ buf.close();@b@ }@b@ catch (IOException ioe)@b@ {@b@ }@b@ }@b@ return object;@b@ }@b@@b@ protected static synchronized List<ExtensionFactory> loadExtensionFactories() {@b@ List factories = _loadimpls("META-INF/services/org.apache.abdera.factory.ExtensionFactory");@b@@b@ return factories;@b@ }@b@@b@ public static synchronized <T> List<T> loadimpls(String sid) {@b@ return loadimpls(sid, false);@b@ }@b@@b@ public static synchronized <T> List<T> loadimpls(String sid, boolean classesonly) {@b@ return _loadimpls(sid, classesonly);@b@ }@b@@b@ protected static <T> List<T> _loadimpls(String sid, boolean classesonly)@b@ {@b@ List impls = Collections.synchronizedList(new ArrayList());@b@ ClassLoader loader = getClassLoader();@b@ try {@b@ Enumeration e = locateResources(loader, sid);@b@ while (e.hasMoreElements()) {@b@ BufferedReader buf = null;@b@ try {@b@ URL url = (URL)e.nextElement();@b@ InputStream is = url.openStream();@b@ if (is != null) {@b@ buf = new BufferedReader(new InputStreamReader(is));@b@@b@ while ((line = buf.readLine()) != null) {@b@ String line;@b@ String s = line.split("#", 2)[0].trim();@b@ if (!("".equals(s))) {@b@ Object impl = locateInstance(loader, s, null);@b@ if (impl != null)@b@ impls.add(impl);@b@ }@b@ }@b@ }@b@ } catch (Exception ex) {@b@ }@b@ finally {@b@ if (buf != null)@b@ try {@b@ buf.close();@b@ }@b@ catch (IOException ioe)@b@ {@b@ }@b@ }@b@ }@b@ }@b@ catch (Exception e)@b@ {@b@ }@b@ return impls;@b@ }@b@@b@ protected static <T> List<T> _loadimpls(String sid)@b@ {@b@ return _loadimpls(sid, false);@b@ }@b@}