EGL作为一门业务语言,提供了一套抽象的面向业务开发的语言模型。EGL程序员能利用这套面向业务的语言模型方便、快捷地开发出跨平台的、跨语言的各种业务系统。EGL针对业务系统里经常用到的数据访问操作定义了一系列语句,比如,
GoogleApp Engine提供了一种不同于关系型数据库的数据存储,基于BigTable的Datastore。通过把EGL数据操作语句扩展到Datastore,EGL使用者可以在不了解Datastore技术细节的情况下轻易写出能够利用Datastore存储的应用程序。甚至可以几乎不做改动的将一个使用SQL存储的程序切换成使用Datastore存储。由此意味着EGL程序员在不改变应用程序的前提下,通过扩展EGL,能毫不费劲地把一个基于Java JDBC关系数据库实现的应用无缝的迁移到任何新出现的平台上(包括我们即将要实现的扩展GAE BigTable DataStore),这样能大大提高应用程序的开发效率和降低开发成本。
这篇blog介绍如何扩展EGL中的add语句来调用GAE的存储API,带领大家一起来学习EGL是如何在语言模型、代码生成器上进行扩展的。
本文的目标是扩展EGL,用于实现和Google App Engine数据存储的集成。我们展示了如何用EGL语言来实现向GoogleApp Engine数据存储中插入实体数据的过程,并给出一个包括EGL Rich UI和EGL REST Service的样例,最终将该样例部署到Google App Engine上。
这里先大概介绍一下进行EGL扩展的策略。
第一,需要先掌握目标扩展平台的相关知识;
第二,参考现有的EGL语言模型,看是否能够适应要扩展的目标平台;
第三,手工先实现一下将要被生成的目标平台的代码,为实现自己的代码生成器做准备;
第四,总结目标生成代码,决定是否有必要提炼出一个目标平台的运行时,以方便代码生成。
3.1和3.2简单概述了扩展EGL的步骤,具体的细节,请参考章节4、5和6。
通常,针对数据模型的存取,EGL会提供一个数据源(DataSource)作为数据存取和访问的入口点。如针对关系数据库,用户可以使用SQLDataSource来进行数据的增、删、改、查。
同样,如果需要向GoogleApp Engine的数据存储(Data Store)进行数据的存取和访问等操作,也需要一个数据源,这就需要我们对已有的EGL模型进行扩展。以下是扩展的一个简单流程:
在扩展完GAEDataSource和相应的EGL模型后,还需要对代码生成器(EGL Generator)进行扩展,从而生成相应的和Google App Engine相集成的Java代码。
基于Java的代码生成器的扩展,一般有两种方式:
在本文中,我们采用第二种方式。关于如何扩展代码生成器,读者可以参考DW中国上的EGL系列文章的第四篇来了解更多详细信息【待定】。
关于如何安装和配置GAE插件,读者可以访问Google App Engine的官方文档https://developers.google.com/appengine/downloads#Download_the_Google_Plugin_for_Eclipse去自行安装和设置。
关于如何安装EDT以及配置EDT等具体的技术细节,读者可以参考在线帮助文档“EGL语言从入门到精通:http://blog.csdn.net/rationalgroup/article/details/7336753”。
检出所需要的插件项目。在这里读者需要注意的是应该检出每个项目的EDT080GM版本,如图所示:
Google App Engine的数据储存代表一个新的数据源,因此在这里我们需要创建一个新的EGL版型GAEDataSource来表示它。
在插件org.eclipse.edt.compiler中新建一个EGL包eglx.gae,并创建一个外部类型(ExternalType)。这个外部类型用于定义一个DataSource,用于和其他DataSource进行区分。
externalType GAEDataSource extends DataSource type NativeType end
GAEDataSource的程序目录结构
创建完外部类型以后,需要运行tools/build-CompilerEGLAR.xml的ANT脚本来在lib目录下编译生成相应的EGLAR文件edtCompiler.eglar。
接下来需要在插件org.eclipse.edt.runtime.java中添加一个空实现的Java类eglx.gae.GAEDataSource.java。具体的程序结构读者可以自行参考附件中的样例程序【
http://download.csdn.net/detail/rationalgroup/4326397】。
在创建完GAEDataSource以后,需要扩展相应的EGL Model来标识和Google AppEngine数据储存相关的模型。在本文中,我们仅给出add语句的样例,读者可以参考这个实现来实现其他的抽象语句(如get, replace, delete)。
首先在EDT中创建一个插件项目org.eclipse.edt.mof.eglx.gae,右击该项目,在右键菜单中选择Configure -> Convert to EGL Project,这样该项目就转换成一个EGL插件项目。
在该项目中创建一个EGL源文件GAEActionStatement.egl:
org.eclipse.edt.mof.eglx.gae插件
运行tools/build-MofEglMOFAR.xml生成egllib下面的mofar和eglar包:gae.eglar和gae.mofar(读者可以拷贝样例程序中的Ant脚本到该项目中)。
这个插件的作用类似于源代码中的org.eclipse.edt.mof.eglx.services插件,具体的Java接口和实现读者可以参考这个插件。
创建完EGL Model以后,我们需要在EGL的Compiler插件org.eclipse.edt.compiler注册这些模型,使得Compiler可以识别这些新定义的EGL Model。
在完成EGL Model的定义和相应的Compiler注册以后,我们需要为这些新定义的EGL Model来定制和扩展相应的EGL Generator,用来产生和Google App Engine集成的Java代码。
新建一个GAE模板项目org.eclipse.edt.gen.java.templates.eglx.gae(读者可以参考SQL相关的模板项目org.eclipse.edt.gen.java.templates.eglx.persistence),并创建相应的模板GAEAddStatementTemplate。源代码如下:
public class GAEAddStatementTemplate extends org.eclipse.edt.gen.java.templates.StatementTemplate { public void genStatementBody(GAEAddStatement stmt, Context ctx, TabbedWriter out) { Expression expression = stmt.getTarget(); Type type = expression.getType(); EGLClass targetType = (EGLClass) type.getClassifier(); String recordName = targetType.getName(); out.println("com.google.appengine.api.datastore.DatastoreService datastore = com.google.appengine.api.datastore.DatastoreServiceFactory.getDatastoreService();"); out.print("com.google.appengine.api.datastore.Entity "); String googleEntity = "google_" + recordName; out.print(googleEntity); out.print(" = new com.google.appengine.api.datastore.Entity( " + "\"" + recordName + "\"" + " )"); out.print(";"); out.println(); for (Field f : targetType.getFields()) { out.print(googleEntity + "." + "setProperty(\""); ctx.invoke(genName, f, ctx, out); TabbedWriter temp = ctx.getTabbedWriter(); ctx.invoke(genExpression, expression, ctx, temp); String varName = temp.getCurrentLine(); out.print("\"," + varName + "."); ctx.invoke(genName, f, ctx, out); out.print(");"); out.println(); } out.print("datastore.put(" + googleEntity + ");"); } } 同时,需要创建一个模板文件用于把新定义的EGL Model和相应的Generator绑定在一起,源文件如下:创建一个EGL RichUI项目“RuiTesting”,选择“Web2.0 client application withservices”作为模板。
在RuiTesting项目里,创建一个EGL Record,源代码如下:
record OrderItem itemId int{@Id};//{@Id, @GeneratedValue }; //NAME string{@GeneratedValue}; name string{ @Column { insertable=true } }; end 创建一个EGL REST Service,源代码如下:Google App Engine的Eclipse插件提供了本地的运行环境。因此,我们在这里介绍一下如何将7.1中开发的样例程序进行部署并在本地运行。
使用EGL Deployment Descriptor Editor来打开RuiTesting/EGLSource/RuiTesting.egldd文件,在Resource Binding标签中,设置URI为http://localhost:8888/restservices/HelloService。
需要注意的是,由于GoogleApp Engine的Eclipse插件所提供的Web Application项目结构并非一个标准的Eclipse下的动态Web项目,为了EGL程序的部署需要,我们需要对GAE的项目结构做一些调整,使得它转换成一个标准的Eclipse动态Web项目。
首先创建一个Google App Engine的项目RuiTestingDeploy,在项目属性的Project Facet中设置DynamicWeb Module的版本为2.4。并设置WAR的目录为WebContent,如图所示。其次在原有的war目录下,将Google App Engine的部署描述符appengine-web.xml和Log4J的配置文件logging.properties拷贝到WebContent目录下。并删除原有的war目录。
开始部署样例程序到RuiTestingDeploy中。部署完毕以后,修改下列文件:
在GAE环境中,运行RuiTesting.html,关于怎么在本地运行GAE程序,读者可以参考GAE的官方文档。
本篇博客只是对EGL中的add语句在GAE平台上的扩展做了初步探讨,接下来需要读者实现对EGL里的其它抽象操作语言(replace, delete和get)的扩展实现,并使用扩展后的基于GAE的EGL实现一个针对数据库访问的应用(前台使用EGLRichUI,后台使用基于GAE的EGL服务),并且需要部署在Google App Engine上。
来源:网络
本系列文章基于公开资料对Google App Engine的实现机制这个话题进行深度探讨。在切入Google App Engine之前,首先会对Google的核心技术和其整体架构进行分析,以帮助大家之后更好地理解Google App Engine的实现。 本篇将主要介绍Google的十个核心技术,而且可以分为四大类: 分布式基础设施:GFS、Chubby 和 Protocol Buffer。 分布...
文章提交保存后,还需要修改或删除,这样GAE的CRUD操作就都全齐了。 首先,在文章列表下面添加修改、删除的链接,通过URL传值的方式提交请求,这里有两个参数,一个是命令(CMD)代表操作的动作是修改(modify)还是删除(delete),一个是主键(KEY)代表需要被编辑的博客文章。 在页面上把这两个操作的链接加上:  ...
《Google App Engine编程:英文版》china-pub预定中 本书相应中文版《GAE编程指南 》 基本信息 作者: (美)Sanderson 出版社:东南大学出版社 ISBN:9787564124939 购买地址:http://www.china-pub.com/197655 基本信息 原书名: Programming Google App Eng...
本文说明如何部署一个GWT应用程序到Google App Engine,本文不对一些名词作解释,直接进行应用。先给出我部署完的链接:http://gwtstarting.appspot.com/,可以先睹为快; Step one:添加插件 Eclipse 3.6 (Helios) http://dl.google.com/eclipse/plugin/3.6 如果你熟悉Ec...
函数都有prototype属性,它指向原型对象。 实例对象有__proto__属性,它指向对象原型 每一个原型对象都有constructor输赢,指向构造函数,每一个原型对象又具有__proto__属性,这个指向Object.prototype.在这里插入图片描述...
2.Dubbo简介 2.1 什么是dubbo Dubbo是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。 2.2 流程图 Provider : 暴露服务的服务提供方。 Consumer : 调用远程服务的服务消费方。 Registry : 服务注册与发现的注册中心。 Monito...
mysql基础入门的总结 关于数据库: 数据库是软件开发人员要掌握的基本工具,软件的运行的过程就是操作数据的过程,数据库中的数据无非就是几个操作:增-删-查-改。 Mysql安装完成后,需要配置变量环境,找到配置路径path,然后把mysql安装目录bin文件导入就可以了。 然后运行cm...
adb常用命令: 查看手机是否连接:adb devices 连接设备:adb connect 设备ip:端口号 若有连接多个设备需指明设备ip及端口号 安装APP:adb install [-r] 包名 -r表示覆盖安装,首次安装可省略 卸载APP:adb uninstall 包名 列出设备中所有应用包名:adb shell pm list packages ...
以谷歌浏览器为例,注意有些浏览器并不支持该功能。 1)打开自定义与控制 2)选择设置 3)查看左边状态栏,选择高级设置--》隐私设置和安全性 4)选择内容设置 5)图片 6)选择不显示任何图片,其中也可以只禁用某些网站图片,或者只开启自己想显示图片的网站...
IDEA中使用springMVC 出现 404请求的资源不可用的其他一个可能原因 如果你确认你在视图解析器中的路径设置没有问题,各种文件名都没问题,却依然出现资源不可用错误 你可以检查这个页面中是否为web部署了工件,没有的话部署一下就好了。...
I'm currently trying out the google cloud messaging service with its sample application "Guestbook." https://developers.google.com/cloud/samples/mbs/ I'm attempting to send notifications tha...
Now I came across an article that distinguishes between an Asynchronous function and Synchronous functions. From my understanding of the different examples and explanations, synchronous functions are ...
Good day all I'm busy creating a small costing calculator for the signage department. I'm not getting the calculator to output the amount. Brief Description: You enter the height and width and then wh...
I have 3 models created with Flask-SQLalchemy: User, Role, UserRole role.py: user.py: user_role.py: If I try (in the console) to get all users via User.query.all() I get AttributeError: 'NoneType' obj...
I have many particles that follow an stochastic process in parallel. For each particle, there is a PRNG associated to it. The simulation must go through many repetitions to get average results. For ea...