• FBReader代码分析:创建BookModel时,如何根据Book来得到对应的FormatPlugin?


    本篇文章暂时只是本人看代码过程中备忘的记录,未详细的整理,条理不太清晰。

    BookModel -> createModel(Book book);

    Book -> getPlugin() -> getPlugin(ZLFile) -> 实际由PluginCollection类获取:

    PluginCollection -> getPlugin(ZLFile) -> getPlugin(file, FormatPlugin.Type.ANY)

        public FormatPlugin getPlugin(ZLFile file, FormatPlugin.Type formatType) {
            final FileType fileType = FileTypeCollection.Instance.typeForFile(file);
            final FormatPlugin plugin = getPlugin(fileType, formatType);
            if (plugin != null && plugin.type() == FormatPlugin.Type.EXTERNAL) {
                return file == file.getPhysicalFile() ? plugin : null;
            }
            return plugin;
        }

    FileTypeCollection类初始化了所有可接受的文件类型:FileTypeCollection

         /**
         * 以FileType的Id为Key,FileType为值存储下来
         */
        private final TreeMap<String, FileType>    myTypes        = new TreeMap<String, FileType>();
    
        private FileTypeCollection()
        {
            addType(new FileTypeFB2());
            addType(new FileTypeEpub());
            addType(new FileTypeMobipocket());
            addType(new FileTypeHtml());
            addType(new SimpleFileType("plain text", "txt", MimeType.TYPES_TXT));
            addType(new SimpleFileType("RTF", "rtf", MimeType.TYPES_RTF));
            addType(new SimpleFileType("PDF", "pdf", MimeType.TYPES_PDF));
            addType(new FileTypeDjVu());
            addType(new SimpleFileType("ZIP archive", "zip", Collections.singletonList(MimeType.APP_ZIP)));
            addType(new SimpleFileType("MS Word document", "doc", MimeType.TYPES_DOC));
        }
    
        private void addType(FileType type)
        {
            myTypes.put(type.Id.toLowerCase(), type);
        }
    
        public Collection<FileType> types()
        {
            return myTypes.values();
        }    

    这些可接受的文件类型集,包括:

    表1:支持的FileType
    FileType 对应Id 实际接受的文件后缀(acceptsFile) mimeTypes
    FileTypeFB2 fb2 .fb2、.fb2.zip application/x-fictionbook、application/x-fictionbook+xml、application/fb2+xml、text/fb2+xml、application/fb2+zip
    FileTypeEpub ePub epub、oebzip、opf application/epub+zip、application/epub
    FileTypeMobipocket Mobipocket pdb、prc、mobi、azw3 application/x-mobipocket-ebook
    FileTypeHtml HTML html、htm text/html、application/html、application/html+htm
    FileTypeDjVu DjVu djvu、djv image/vnd.djvu、image/x-djvu、application/djvu
    SimpleFileType plain text txt text/plain、application/txt
    SimpleFileType RTF rtf application/rtf、text/rtf
    SimpleFileType PDF pdf application/pdf
    SimpleFileType ZIP archive zip application/zip
    SimpleFileType MS Word document doc application/msword、application/doc

    可以根据传入的ZLFile得到该ZLFile所被支持的FileType对象:FileTypeCollection -> typeForFile(ZLFile file)

       public FileType typeForFile(ZLFile file)
        {
            for (FileType type : types()) {
                if (type.acceptsFile(file)) {
                    return type;
                }
            }
            return null;
        }

    实际获取FormatPlugin的方法PluginCollection -> getPlugin(FileType fileType, FormatPlugin.Type formatType)

      public FormatPlugin getPlugin(FileType fileType, FormatPlugin.Type formatType) {
            if (fileType == null || formatType == null) {
                return null;
            }
    
            switch (formatType) {
                case ANY:
                {  
                    FormatPlugin p = getPlugin(fileType, FormatPlugin.Type.NATIVE);// 优先获取Native的FormatPlugin
                    if (p == null) {// 加载不到时才加载Java的FormatPlugin
                        p = getPlugin(fileType, FormatPlugin.Type.JAVA);
                    }
                    if (p == null) {// 再加载不到时,加载扩展的FormatPlugin
                        p = getPlugin(fileType, FormatPlugin.Type.EXTERNAL);
                    }
                    return p; }
    default: { final List<FormatPlugin> list = myPlugins.get(formatType); if (list == null) { return null; } for (FormatPlugin p : list) {
                // p.supportedFileType()实际返回的是初始化FormatPlugin时传入的myFileType(从表2查看);
                // FileType的Id值(从表1查看)将于FormatPluginmyFileType进行匹配,匹配上了边返回对应的FormatPlugin
    if (fileType.Id.equalsIgnoreCase(p.supportedFileType())) { return p; } } return null; } } }

    1.首先默认进入了ANY,递归再次进入,携带的formatType为FormatPlugin.Type.NATIVE
    ,然后进入的是default。

    2.然后得由这个formatType去得到List<FormatPlugin>。现在需要知道myPlugins是怎么来初始化的?
    // ======================= 以下代码便是myPlugins的初始化过程=======================
    private final Map<FormatPlugin.Type,List<FormatPlugin>> myPlugins =
            new HashMap<FormatPlugin.Type,List<FormatPlugin>>();


    public
    static PluginCollection Instance() { if (ourInstance == null) {
           // 这里初始化所有支持的FormatPlugin实例
           // 1.MobipocketPlugin -> FormatPlugin.Type.Java
           // 2.DjVuPlugin -> FormatPlugin.Type.EXTERNAL
           // 3.PDFPlugin -> FormatPlugin.Type.EXTERNAL
           ourInstance
    = new PluginCollection();
           
    // This code can not be moved to constructor because nativePlugins() is a native method for (NativeFormatPlugin p : ourInstance.nativePlugins()) { ourInstance.addPlugin(p); System.err.println("native plugin: " + p); } } return ourInstance; } private PluginCollection() { addPlugin(new MobipocketPlugin()); if (Build.VERSION.SDK_INT >= 8) { addPlugin(new DjVuPlugin()); addPlugin(new PDFPlugin()); } } private void addPlugin(FormatPlugin plugin) { final FormatPlugin.Type type = plugin.type(); List<FormatPlugin> list = myPlugins.get(type); if (list == null) { list = new ArrayList<FormatPlugin>(); myPlugins.put(type, list); } list.add(plugin); }

    private void NativeFormatPlugin[] nativePlugins();
    myPluginsFormatPlugin.Type为Key存储了对应FormatPlugin.Type的所有FormatPlugin。

    FormatPlugin.Type的所有类型:FormatPlugin -> enum Type:
    public enum Type {
            ANY,
            JAVA,
            NATIVE,
            EXTERNAL;
        };
    表2:支持的FormatPlugin
    某FormatPlugin子类 该类的myFileType 其对应父类 该类的Type
    BuiltinFormatPlugin(abstract)   FormatPlugin(abstract)  
    JavaFormatPlugin(abstract)   BuiltinFormatPlugin(abstract) Type.JAVA
    NativeFormatPlugin   BuiltinFormatPlugin(abstract) Type.NATIVE
    FB2NativePlugin  fb2 NativeFormatPlugin Type.NATIVE
    OEBNativePlugin  ePub NativeFormatPlugin Type.NATIVE
    MobipocketPlugin  Mobipocket JavaFormatPlugin(abstract) Type.JAVA
    ExternalFormatPlugin(abstract)   FormatPlugin(abstract) Type.EXTERNAL
    DjVuPlugin  DjVu ExternalFormatPlugin(abstract) Type.EXTERNAL
    PDFPlugin  PDF ExternalFormatPlugin(abstract) Type.EXTERNAL

    打开某一个epub资源 example.epub ,断点进入时,下面是所有FileType的值:

    {
    djvu=org.geometerplus.zlibrary.core.filetypes.FileTypeDjVu@52ddbe84, 
    epub=org.geometerplus.zlibrary.core.filetypes.FileTypeEpub@52dda188, 
    fb2=org.geometerplus.zlibrary.core.filetypes.FileTypeFB2@52dd9fd8, 
    html=org.geometerplus.zlibrary.core.filetypes.FileTypeHtml@52dda6d0, 
    mobipocket=org.geometerplus.zlibrary.core.filetypes.FileTypeMobipocket@52dda4e8, 
    ms word document=SimpleFileType [MS Word document], 
    pdf=SimpleFileType [PDF], 
    plain text=SimpleFileType [plain text], 
    rtf=SimpleFileType [RTF], 
    zip archive=SimpleFileType [ZIP archive]
    }

    下面是所有FormatPlugin的值:

    可以看出共有六种类型的FormatPlugin当前被支持了。
    因此,上面的example.epub资源,其对应的FileType是epub=org.geometerplus.zlibrary.core.filetypes.FileTypeEpub[ePub],FormatPlugin是OEBNativePlugin[ePub]。



     

     

     

     

     

     
     
     
     
  • 相关阅读:
    JavaScript : 零基础打造自己的类库
    Basler和Matrox的配置及调试
    StanFord ML 笔记 第十部分
    StanFord ML 笔记 第九部分
    凸优化&非凸优化问题
    一些误差的概念
    StanFord ML 笔记 第八部分
    StanFord ML 笔记 第六部分&&第七部分
    StanFord ML 笔记 第五部分
    大数定律和中心极限定律
  • 原文地址:https://www.cnblogs.com/emmet7life/p/4210684.html
Copyright © 2020-2023  润新知