[zt]EMF.Edit编程学习笔记之一: Item Provider机制

本文介绍了Eclipse Modeling Framework (EMF) 中PropertySheet的实现原理,包括IPropertySourceProvider、IPropertySource等接口的作用,以及EMF如何通过ItemProvider机制为模型对象提供属性编辑功能。

FROM:http://www.blogjava.net/eclipshine/archive/2005/07/29/8754.html

(注:大部分翻译,整理自Eclipse Modeling Framework: A Developer's Guide一书的第3.1, 3.2节的内容)


Porvider的概念<o:p></o:p>

对于JFace部分的内容已经比较清楚,这里重点看一下EclipsePropertySheet是如何实现的。这涉及到了三个接口,IPropertySourceProviderIPropertySourceIPropertyDescriptor。而模型对象如果要能够与PropertySheet进行交互,则必须实现IPropertySource接口。Eclipse能够自动的通过IPropertySourceProvider(当然也不是自动,用到了Eclipse中的Adapter技术),取得这个实现了IPropertySource的模型对象,并让PropertySheet对其进行调用。IPropertySourcegetPropertyDescriptors()方法取得所有的属性描述对象,属性描述对象定义了一个显示在PropertySheet中的属性的名称等一些相关的性质。IPropertySource中的其它方法,提供了对属性值的显示与修改的方法。

image001.png

<o:p></o:p>

<v:shapetype id="_x0000_t75" path=" m@4@5 l@4@11@9@11@9@5 xe" o:preferrelative="t" filled="f" stroked="f" coordsize="21600,21600" o:spt="75"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0 "></v:f><v:f eqn="sum @0 1 0 "></v:f><v:f eqn="sum 0 0 @1 "></v:f><v:f eqn="prod @2 1 2 "></v:f><v:f eqn="prod @3 21600 pixelWidth "></v:f><v:f eqn="prod @3 21600 pixelHeight "></v:f><v:f eqn="sum @0 0 1 "></v:f><v:f eqn="prod @6 1 2 "></v:f><v:f eqn="prod @7 21600 pixelWidth "></v:f><v:f eqn="sum @8 21600 0 "></v:f><v:f eqn="prod @7 21600 pixelHeight "></v:f><v:f eqn="sum @10 21600 0 "></v:f></v:formulas><v:path o:extrusionok="f" o:connecttype="rect" gradientshapeok="t"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype>

图摘自(Eclipse Modeling Framework: A Developer's Guide<o:p> </o:p>

因此可以看到,要实现一个Tree Viewer,则必须有一个实现了ITreeContentProvider 接口的对象为其提供内容,有一个ILabelProvider接口对象为其提供显示的标签和图标。对于PropertySheet也是如此,必须有一些实现了IPropertyDescriptors()接口的对象来提供被编辑的属性描述。EMF.Edit要做的就是这样的一个工作:它为EMF模型对象,为这些不同的Viewer生成Provider,使得EMF模型对象能够通过那些Viewer进行显示与编辑。EMF.Edit能够通过两种方式来完成这样的工作,反射机制,以及代码生成的机制。并且EMF.Edit允许方便的更改所生成的代码,使得其能够满足特定的要求。

<o:p></o:p>

EMF.Edit中对EMF模型对象的改变,都是通过一种通用的机制:Command来实现的。EMF.Edit提供了对一些常见的Command的实现,并可支持自定义的Command。从上面的讨论可以大概的了解到,EMF.Edit提供的是在Eclipse的界面(JFace, PropertySheet, etc)同EMF模型对象之间的一个桥梁,使得能够通过Eclipse UI来显示和修改EMF所定义的模型对象。EMF.Edit分为两个部分:

1.         org.eclipse.emf.edit: 提供的是底层的与界面无关的部分。

2.         org.eclipse.emf.edit.ui: 提供的是与Eclipse UI相关的实现类。

<o:p></o:p>

EMF.Edit中最重要的概念是Item ProviderEMF.Edit使用一种代理机制,使得大部分与模型对象相关的功能都最终被代理到相关的Item Provider上了。因此Item Provider需要完成下面这4种主要的功能:

1.         实现content label provider 的功能。

2.         EMF objects提供PropertySource的功能。

3.         作为Command Factory为模型对象创建相关的Command

4.         EMF模型改变通知到Viewers

特定的Item Provider通常通过继承ItemProviderAdapter类来完成全部或者部分的上述功能。Item Provider可以通过代码生成机制被生成后然后进行适当的修改以满足要求;另一方面,EMF.Edit也提供了ReflectiveItemProvider,通过EObject的反射机制实现了上述所有的功能。

<o:p></o:p>



下面看上述的功能是如何在
EMF.Edit中被实现的。<o:p></o:p>

<o:p></o:p>

实现content label provider 的功能<o:p></o:p>

EMF.Edit提供了通用的AdapterFactoryContentProviderAdapterFactoryLabelProvider实现。也就是说对于一个TableViewer而言,它使用AdapterFactoryContentProviderAdapterFactoryLabelProvider作为其ContentProviderLabelProviderAdapterFactoryContentProvider等再将请求转发到具体的Item Provider上。转发的过程如下所示,在AdapterFactoryContentProvider中实现的ContentProvider所定义的getChildren()方法:

       public Object[] getChildren(Object object) {<o:p></o:p>

              ITreeItemContentProvider adapter = (ITreeItemContentProvider) adapterFactory<o:p></o:p>

                            .adapt(object, ITreeItemContentProvider.class);<o:p></o:p>

              return adapter.getChildren(object).toArray();<o:p></o:p>

       }<o:p></o:p>

AdapterFactoryContentnProvide通过其adapterFactory,将模型对象object适配到ITreeItemContentProvider上(注意ITreeContentProviderITreeItemContentProvider名称上的区别),然后调用相应的方法。这里用到的adapter的模式,在EclipseEMF中使用的非常广泛

<o:p> image003.png</o:p>

图摘自(Eclipse Modeling Framework: A Developer's Guide<o:p> </o:p>

ITreeContentProviderITreeItemContentProvider虽然名称上有区别,但其实际上功能是类似的,EMF中之所以引入ITreeItemContentProvider,是为了避免对JFace这样的UI包的依赖,使得其能够用到其它的非UI或者非JFace的环境中。这样的接口有:

l         ITreeItemContentProvider

l         IStructuredItemContentProvider

l         ITableItemLabelProvider

l         IItemLabelProvider

分别对应于JFace中去掉了Item后的接口。

<o:p></o:p>

EMF objects提供PropertySource的功能<o:p></o:p>

AdapterFactoryContentProvider实际上也实现了IPropertySourceProvider接口,使用如上所述的相同的方式,将模型对象适配到一个IItemPropertySource接口上,对应于IPropertySource。另外的一个EMFPropertySource通过封装IItemPropertySource实现了PropertySheet所需要的IPropertySource接口,并被AdapterFactoryContentProvider所返回。同样的模式被使用到生成IPropertyDescriptorEMF实现PropertyDescriptor上。下面的这个图可以比较清楚的看到这样的关系。

<o:p> image005.png</o:p>

图摘自(Eclipse Modeling Framework: A Developer's Guide

<o:p></o:p>

作为Command Factory为模型对象创建相关的Command<o:p></o:p>

EMF有其自生的Command框架。在这个框架中,EditingDomain是一个类是于JFace中的Provider的接口,提供对Command的创建。并且,EMF.Edit也有一个实现了这个接口的AdapterFactoryEditingDomain,并将请求转发到被适配的IEditingDomainItemProvider对象上。

<o:p></o:p>

EMF模型改变通知到Viewers<o:p></o:p>

Item Provider作为标准的EMF Adapter,当被适配的模型对象发生改变的时候Item ProvidernotifyChanged()会被调用。实际上,ItemProvidernotifyChange()只是将请求(经过过滤后)转给相应的ItemProviderAdapterFacotry,使得其作为模型事件注册及响应的中心。如下图所示:

<o:p> image007.png</o:p>

图摘自(Eclipse Modeling Framework: A Developer's Guide

<o:p></o:p>

需要注意的是,在这样情景下,作为内容显示部分的Viewer并不是事件监听者,相应的Provider对象才是,它监听事件,并调用Viewerupdate()方法以刷新显示的内容。

我在PHP-FPM配置配置中,新增了以下系统环境变量:env[LD_LIBRARY_PATH] = /usr/local/gcc-12.1.0/lib64: env[LESSOPEN] = \|\|/usr/bin/lesspipe.sh %s env[PATH] = /usr/local/gcc-12.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin env[LS_COLORS] = rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:
最新发布
03-11
<think>好的,我现在需要帮助用户解决他们在PHP-FPM配置中添加环境变量后可能遇到的问题。用户之前已经遇到了配置错误和模块重复加载的问题,现在他们在配置文件中新增了几个环境变量,但可能出现了问题。我需要仔细分析他们提供的配置内容,找出潜在的问题,并给出解决方案。 首先,用户新增的环境变量包括LD_LIBRARY_PATH、LESSOPEN、PATH和LS_COLORS。这些变量看起来都是系统环境变量,可能用于设置库路径、路径变量以及颜色配置等。不过,用户在PHP-FPM中设置这些变量时需要注意语法和安全性。 我需要检查用户提供的配置语法是否正确。例如,在PHP-FPM的配置文件中,设置环境变量应该使用正确的语法,比如`env[VAR_NAME] = $VAR_VALUE`。用户提供的配置中,是否有语法错误?比如,是否遗漏了等号两边的空格,或者在变量值中是否有特殊字符没有正确转义? 例如,用户写的`env[LESSOPEN] = \|\|/usr/bin/lesspipe.sh %s`,这里的双竖线被转义了,是否正确?在PHP-FPM配置中,是否需要对某些字符进行转义?可能需要验证这一点,或者查看PHP-FPM的文档。 另外,PATH变量的设置是否正确?用户将PATH设置为包含多个路径,用冒号分隔。这在Unix系统中是标准的,但在PHP-FPM中设置PATH是否会有影响?比如,是否会导致PHP进程在执行外部命令时使用这个PATH,是否存在安全风险? 接下来,LS_COLORS变量的值非常长,包含很多分号和颜色代码。在配置文件中,分号通常是注释符号,所以这里可能需要用引号将整个值括起来,或者使用其他方式避免分号被解析为注释。例如,用户是否应该将LS_COLORS的值用双引号包裹,以防止分号被错误解析? 例如,用户配置的`env[LS_COLORS] = rs=0:di=01;34:...`,这里的分号在配置文件中可能被当作注释的开始,导致后面的内容被忽略。因此,正确的做法应该是将整个值用引号括起来,如`env[LS_COLORS] = "rs=0:di=01;34:..."`,这样分号就不会被错误处理了。 此外,用户是否在配置中正确设置了每个环境变量?是否有拼写错误,比如变量名是否正确,比如LESSOPEN是否正确,或者是否有大小写问题? 还需要考虑这些环境变量是否真的需要在PHP-FPM中设置。例如,LS_COLORS通常用于控制ls命令的颜色显示,而PHP-FPM进程可能不需要这个变量,除非有特定的脚本依赖它。设置不必要的环境变量可能会增加配置复杂性和潜在的安全风险。 另外,用户之前遇到的问题是PHP-FPM启动失败,可能是因为配置文件中的语法错误。现在用户新增了这些环境变量,可能导致新的语法错误,比如在LS_COLORS中的分号导致解析错误,或者转义字符不正确。 解决方案方面,可能需要建议用户检查每个环境变量的语法,特别是处理分号和特殊字符的情况。对于包含分号的值,使用引号包裹。同时,验证PATH的设置是否合理,避免安全风险,比如包含不安全的路径。此外,检查是否有重复的环境变量定义,或者是否有变量名冲突。 可能还需要提醒用户,在修改配置后,使用`php-fpm -t`命令测试配置文件的正确性,然后再重启服务。如果测试命令报错,可以根据错误信息定位具体的行和问题。 总结一下,用户的问题可能出在LS_COLORS中的分号导致配置文件解析错误,以及转义字符是否正确使用。需要指导用户正确转义或引用这些值,并验证其他变量设置的正确性。</think>--- ### 一、当前配置的核心问题 从您提供的PHP-FPM环境变量配置来看,**`LS_COLORS`** 的定义会导致语法错误,且部分变量格式需要调整。以下是关键问题分析: 1. **`LS_COLORS` 中的分号引发语法错误** PHP-FPM配置文件会将`;`(分号)识别为注释符号,而`LS_COLORS`的值包含大量分号(如`di=01;34`),导致解析中断。 **示例错误**: ```nginx env[LS_COLORS] = rs=0:di=01;34:... # PHP-FPM会将`;34:...`视为注释 ``` 2. **`LESSOPEN` 变量转义符多余** `\|\|`中的反斜杠在PHP-FPM配置中会被保留,可能导致路径解析错误(实际应为`||`)。 3. **潜在风险** - 设置`LD_LIBRARY_PATH`可能影响PHP依赖库的加载优先级,需谨慎。 - 覆盖系统`PATH`可能导致系统命令调用异常(如`/usr/bin`被覆盖)。 --- ### 二、修复步骤 #### 步骤1:修复`LS_COLORS`的分号问题 用双引号包裹变量值,防止分号被识别为注释: ```nginx env[LS_COLORS] = "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36" ``` #### 步骤2:修正`LESSOPEN`的转义符 移除多余的转义符,直接使用管道符号: ```nginx env[LESSOPEN] = ||/usr/bin/lesspipe.sh %s ``` #### 步骤3:优化`PATH`定义 保留系统默认路径,优先添加自定义路径(避免覆盖系统命令): ```nginx env[PATH] = /usr/local/gcc-12.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:$PATH ``` --- ### 三、完整配置示例 ```nginx env[LD_LIBRARY_PATH] = /usr/local/gcc-12.1.0/lib64 env[LESSOPEN] = ||/usr/bin/lesspipe.sh %s env[PATH] = /usr/local/gcc-12.1.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:$PATH env[LS_COLORS] = "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:...(略)" ``` --- ### 四、验证与测试 1. **语法检查**: ```bash sudo php-fpm73 -t # 替换为实际PHP版本命令 ``` 输出应为:`Configuration file is OK` 2. **重启PHP-FPM**: ```bash sudo systemctl restart php-fpm73 ``` 3. **验证环境变量**: 创建测试脚本`/var/www/html/test.php`: ```php <?php echo getenv('LD_LIBRARY_PATH') . "\n"; echo getenv('LS_COLORS') . "\n"; ``` 访问后检查输出是否符合预期。 --- ### 五、注意事项 1. **安全性**: - 避免将敏感信息(如密钥)通过`env[]`暴露给PHP进程。 - `LD_LIBRARY_PATH`可能影响依赖库加载,确保路径中库文件可信。 2. **性能影响**: - `LS_COLORS`这类长字符串可能略微增加内存占用,若无必要建议移除。 --- 通过上述调整,PHP-FPM应能正常加载环境变量。若仍有问题,建议提供`php-fpm.conf`完整配置片段进一步排查。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值