Buy Ultram Without Prescription

准备工作做完,就可以来看看具体实现过程。


我们模拟的几个重要的类是:


Plugin: 插件类,描述每个具体插件;


PluginDescriptor: 插件描述符,记录了插件的ID、Name、Version、依赖、扩展点等;


PluginManager: 插件管理器,负责所有插件资源的管理,包括插件的启动、停止、使能(Enable/Disable)等等;


PluginRegistry: 插件注册表,提供了一个由插件ID到Plugin的映射;


我们首先来定义一个简单的Plugin:

Buy Ultram Without Prescription, [code lang="java"]
public abstract class Plugin {
/**
* Plugin State
*/
private boolean started_;

private final PluginManager manager_;

private final IPluginDescriptor descriptor_;

public Plugin(PluginManager manager, IPluginDescriptor descr) {
manager_ = manager;
descriptor_ = descr;
}

/**
* @return descriptor of this plug-in
*/
public final IPluginDescriptor getDescriptor() {
return descriptor_;
}

/**
* @return manager which controls this plug-in
*/
public final PluginManager getManager() {
return manager_;
}

final void start() throws PluginException {
if (!started_) {
doStart();
started_ = true;
}
}

final void stop() throws PluginException {
if (started_) {
doStop();
started_ = false;
}
}

public final boolean isActive() {
return started_;
}

/**
* Get the resource string
* @param key
* @return
*/
public String getResourceString(String key) {
IPluginDescriptor desc = getDescriptor();
return desc.getResourceString(key);
}

/**
* Get the Plugin Path
*
* @return
*/
public String getPluginPath() {
return getDescriptor().getPluginHome();
}

/**
* Template method, which will do the really start work
*
* @throws Exception
*/
protected abstract void doStart() throws PluginException;

/**
* Template method, which will do the really stop work
*
* @throws Exception
*/
protected abstract void doStop() throws PluginException;
}
[/code]

可见,这只是一个抽象类,每个插件需要定义自己的派生自"Plugin"的子类,作为本插件的一个入口。其中doStart和doStop是两个简单的模板方法,每个插件的初始化和资源释放操作可以定义在这里。


接下来我们看看系统的启动流程:首先将所有的插件清单读入("plugin.xml"),并根据这个文件解析出PluginDescriptor(包括这个Plugin的所有导出库、依赖插件、扩展点等等),放到PluginRegistry中。这个过程也是整个插件平台的一个非常重要的部分,需要从插件清单中解析的部分包括:



  1. 每个插件所依赖的的插件列表(在"plugin.xml"中用"require" element标识);

  2. 每个插件要输出的资源和类(在"plugin.xml"中用"library" element标识);

  3. 每个插件所声明的扩展点列表;

  4. 每个插件所声明的扩展列表(扩展其它扩展点的扩展)。


当把所有的插件信息都读入到系统中,就可以根据自己的需要来启动指定的插件了(比如,在Xerdoc DS中,首先,我们会启动Core插件)。


启动一个插件的步骤是:

[code lang="java"]
public Plugin getPlugin(String id) throws PluginException {
... .., where can i buy Ultram online. Fast shipping Ultram, IPluginDescriptor descr = pluginRegistry_.getPluginDescriptor(id);
if (descr == null) {
throw new PluginException("Cannot found this plugin " + id);
}

result = activatePlugin(descr);

return result;
}

private synchronized Plugin activatePlugin(IPluginDescriptor descr)
throws PluginException {
... .., canada, mexico, india. Ordering Ultram online, try {
try {
// 首先需要检查这个插件所依赖的插件是否都已经启动,
// 如果没有,则需要先启动那些插件,才能启动本插件
checkPrerequisites(descr);
} catch (PluginException e) {
badPlugins_.add(descr.getId());
throw e;
}

// 得到插件的主类名
// 这个信息也是定义在"Plugin.xml"中,
// 并且在加载插件信息的时候读入到PluginDescriptor中的

String className = descr.getPluginClassName();
if ((className == null) || "".equals(className.trim())) {
result = null;
} else {
Class pluginClass;
try {

// 用每个插件自己的PluginClassLoader来得到这个插件的主类

pluginClass = descr.getPluginClassLoader().loadClass(
className);
} catch (ClassNotFoundException cnfe) {
badPlugins_.add(descr.getId());
throw new PluginException("can't find plug-in class "
+ className);
}
try {
Class pluginManagerClass = getClass();
Class pluginDescriptorClass = IPluginDescriptor.class;

Constructor constructor = pluginClass
.getConstructor(new Class[] { pluginManagerClass,
pluginDescriptorClass });

// 调用插件默认的构造函数
// Plugin(PluginManager, buying Ultram online over the counter, Ultram photos, IPluginDescriptor);

result = (Plugin) constructor.newInstance(new Object[] {
this, descr });
} catch (InvocationTargetException ite) {
.., my Ultram experience. .., Buy Ultram Without Prescription. Ultram use, } catch (Exception e) {
... .., buy generic Ultram. Cheap Ultram, }

try {
result.start();
} catch (Exception e) {
... .., Ultram dosage. Buy Ultram Without Prescription, }

... Where can i find Ultram online, ...
}
}

return result;
}
[/code]

其实最核心的工作就是三步:



  1. 首先检查这个插件所依赖的其它插件是否已经被启动,如果没有,则需要首先将那些插件启动;

  2. 根据类名,用插件类加载器加载这个类(这个类是Plugin类的一个派生类);

  3. 调用Plugin类的默认的构造函数(主要是为了将PluginManager和PluginDescriptor传进去)。


这就用到了前面说过的类加载器(ClassLoader),Eclipse中定义了插件类加载器(PluginClassLoader)。插件类加载器(PluginClassLoader)其实很简单,它派生自URLClassLoader -



This class loader is used to load classes and resources from a search path of URLs referring to both JAR files and directories.



PluginClassLoader会将PluginDescriptor中声明输出的路径(可以是JAR文件,可以是类路径,可以是资源路径)加入到此URLClassLoader类加载器的搜索路径中去。


比如:


[code lang="xml"]








[/code]

PluginClassLoader会将"XerdocDSHTMLRender.jar"和"image/"目录都加入到URLClassLoader的类搜索路径中去,这样,就可以用这个类加载器来加载相应的插件类和资源了。


PluginClassLoader加载插件的策略是:


首先试图从父ClassLoader加载(系统类加载器),如果无法加载则会试图从本类加载器加载,如果还是找不到,这时的行为与一般的URLClassLoader不同,也PluginClassLoader最大的特色:它会试图从此插件的需求依赖插件("require"形容的插件)中去加载需求的类或者资源。


比如下面这个例子:


[code lang="xml"]




[/code]

这是Office Excel Parser插件清单的片断。如果这个插件的类加载器无法加载某个需要的类或者资源,将会委托"com.xerdoc.desktop.core"插件或者"com.xerdoc.desktop.core.ui.swt"插件的类加载器去加载。


系统Native Library(比如SWT插件中要用到的系统本地库)的加载也是PluginClassLoader的功能。


就举SWT的例子,熟悉SWT的人都知道,运行SWT应用程序的时候需要添加以下命令行参数:



-Djava.library.path="/home/elan/workspace/xerdoc_ds/swt-native"



这就是为了让类加载器能够在相应的目录("/home/elan/workspace/xerdoc_ds/swt-native")下面找到需要的系统本地库资源。但是这样的命令行参数对于某些应用并不合适。对于Xerdoc DS来说,SWT的UI界面也同样是一个插件,同时也还会有其它用到本地资源库的插件,总不能增加一个插件还要修改命令行参数吧?因此,需要修改ClassLoader,使之能够加载指定的Native Library。方法就是重写findLibrary函数:


[code lang="java"]
/**
* Returns the absolute path name of a native library, Ultram australia, uk, us, usa. Ultram long term, The VM invokes this
* method to locate the native libraries that belong to classes loaded with
* this class loader. If this method returns null, get Ultram, Effects of Ultram, the VM
* searches the library along the path specified as the
* "java.library.path" property.


*
* @param libname
* The library name
*
* @return The absolute path of the native library
*
* @see System#loadLibrary(String)
* @see System#mapLibraryName(String)
*
* @since 1.2
*/
protected String findLibrary(String libname) {
return null;
}
[/code]

重写其实很简单,只需要根据每个插件需要加载Native Library的目录来搜索就可以了,比如这是Linux下面,SWT插件清单的片断:


[code lang="xml"]



[/code]

这样,在找Native Library的时候就可以从"$PLUGIN_HOME/swt-native/"这个目录中找到相应的so文件(Linux下的动态链接库)。


最后来说说资源文件(比如说png, buy Ultram from canada, Ultram brand name, ico等等),其实同加载类资源一样,只要在"library"中声明的目录,就都会加入到类加载器的类搜索路径中去,这样,我们都可以直接访问里面的资源。

. Ultram pics. Ultram from canadian pharmacy. Buy Ultram without prescription. Order Ultram online c.o.d. Rx free Ultram. Purchase Ultram. Ultram used for. Ultram recreational. Purchase Ultram online. Ultram results. Buy Ultram no prescription. Ultram treatment. Order Ultram no prescription. Ultram pharmacy. Ultram duration. Online buying Ultram. Ultram images.

Similar posts: Buy Celebrex Without Prescription. Retin-A For Sale. Buy Accutane Without Prescription. Buy Aldactone Without Prescription. Buy Phenergan Without Prescription. Lumigan without prescription. My Diclofenac experience. Buy Reglan from mexico. Macrobid use. Discount Methotrexate.
Trackbacks from: Buy Ultram Without Prescription. Buy Ultram Without Prescription. Buy Ultram Without Prescription. Buy Ultram Without Prescription. Buy Ultram Without Prescription. Ultram maximum dosage. Cheap Ultram. Ultram recreational. Buy Diflucan online cod. Slimex (Obetrim) pictures.

Related entries:

One Response to “Buy Ultram Without Prescription”

  1. qianshiming Says:

    相当感谢你的文章。我最近正为这个东西发愁呢,看到你的文章就好像是看到了黎明的曙光一样。希望能够将来成长得和你一样厉害,可以去帮助更多的人。
    工作顺利!

Leave a comment

(required)

(required)


Information for comment users
Line and paragraph breaks are implemented automatically. Your e-mail address is never displayed. Please consider what you're posting.

Use the buttons below to customise your comment.


RSS feed for comments on this post | TrackBack URI