邋遢居

我的Java天堂

  语源科技BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  61 Posts :: 2 Stories :: 90 Comments :: 0 Trackbacks

2007年1月8日 #

在过去的一年中。断断续续的使用了一些Grails。用他做了点东西。觉得不错,所以希望更多的人来了解他。使用他。所以录制了一点视频,和大家分享。视频会不定期持续更新!

第一集 Grails 开发环境准备

http://v.youku.com/v_show/id_XNjUxNjgxMjA4.html

 

第二集 配置使用 Grails Spring security

http://v.youku.com/v_show/id_XNjY2MDc4MDgw.html

 

第三集  Grails中数据库连接

http://v.youku.com/v_show/id_XNjk4NTM2NDgw.html

posted @ 2014-04-23 22:49 Jet Geng 阅读(2540) | 评论 (0)编辑 收藏

原起

EverNote 的强大已经无需多说。他自己有很好的客户端,不过那个只是对Windows和OS X。在linux下面就虾米菜了。就是Windows和OS X下面的客户端也存在一个致命的弱点:不支持 MarkDown
不过有好人做了一个工具 Geeknote 让我们可以在任何装有python的机器上使用Evernote。 更强大的是他可以使用任何编辑器编辑笔记,支持 MarkDown 。 有如此好处还等什么啊赶紧用起来。
个人在使用的时候发现原版有点点不舒服的地方,做了点点小改动放在了 GitHub。 具体是什么改动,先买个关子。

安装

直接从源码安装

  1. 使用 git clone git@github.com:jetgeng/geeknote.git 命令下载源码
  2. 进入 geeknote 目录。
  3. 运行 python geeknote.py login 登录evernote
  4. 通过 python geeknote.py create , python geeknote.py edit , python geeknote.py find 命令来创建,编辑和查询你的ervernote 中的笔记。
  5. 通过 python geeknote.py settings --editor vim 命令把编辑Evernote的编辑器设定成我最喜欢的vim。 当然你可以设定成你喜欢的。
  6. 这个时候你已经用上了GeekNote。 但是还会有点不爽。最起码我这个时候不爽。

不爽的地方

  1. 当我用python geeknote.py edit 命令使用vim打开我要编辑的笔记时,笔记居然没有把 MarkDown 语法给我高亮出来! 不爽!!
  2. 输入命令一定要带一个什么python 之类的太繁,而且我tab的时候也没有给我把命令补全!在命令行中没有自动补全,太不爽了!!

改之

让vim正确设定filetype

在 vim中一般是根据文件的后缀名来识别该文件是什么类型。然后为他加载相应的语法高亮,代码补全什么的。在没有改动前geeknote是为笔记创建的临时 文件时没有后缀的。只是随机的创建一个形如 tmpsNbc8k这样的文件。所以Vim无法识别他是何种文件,就无法为他加载对于的语法高亮之类的。

既然找到原因了就先看一下geeknote是否有什么地方可以设定,让他产生的临时文件有后缀。最后在editor.py文件中发现了这么一行代码: (tmpFileHandler, tmpFileName) = tempfile.mkstemp() 。 直接没有给任何后缀的想法。
那就加上吧。
我所做的动作就是这个,给他加上了一个文件后缀的设定。
通过python geeknote settings --suffix suffix 这样的命令来设定零时文件的后缀。这样语法高亮,代码补全就回来了。小爽一下!

命令行自动补全

这个其实geeknote已经想到了,而且已经做了。代码仓库中的那个 bash_completion/geeknote 文件就是干这个活的。 所以我只要把这个文件copy到 /etc/bash_completion.d/ 下就可以了。
但是copy进去后没有达到我想要的效果。没有自动补全。最后发现是geeknote配置的补全命令和我们执行的时候不一致。
下面要做的就是把它们搞一致了。
我的操作步骤如下:
1. chmod +x geeknote.py 给geeknote.py加上可执行权限。
2. 将geeknote.py所在路径加入到PATH中去。
3. 修改 /etc/bash_completion.d/geeknote 文件中的 geeknote 为geeknote.py 这个在我上面提到的github中可以找到。

这个时候在新开一个控制台,输入 geeknote.py tab 可以自动补全了。小爽一下!

posted @ 2013-05-31 22:57 Jet Geng 阅读(8389) | 评论 (1)编辑 收藏


Gemini测试小工具

作 者: Jet Geng
日 期: 2011-07-22

概述

Blueprint 起步中我们已经成功的通过 Blueprint 容器创建了一个POJO。我们只是通过log的方式查看到我们的POJO已经被创建了。无法深入的去了解容器内部Bean的运行状态和行为。 所以才有必要创建一个Gemini控制台这样的程序。这个控制台最初的需求是:

  • 能够动态查看特定的Bean是否被创建。
  • 能够动态的获取特定的Bean。
  • 能够检查特定Bean的行为是否正确。

解决方案

为了解决以上的问题。我做了一个小工具。 这个小工具的目的让客户的动态脚本能在最终的目标环境中运行。使用方式如下:
  1. 从 git://github.com/jetgeng/OSGi.git 下载 org.gunn.gemini.consoleorg.codehaus.groovy 这两个项目。
  2. 并把这两项目加入到你的TargetPlatform中。
  3. 使用 invokegv 来运行groovy脚本。
    1. 直接在命令行输入脚本。例如: invokegv print act.getBean(''myPOJO'')
    2. 通过输入Groovy文件。例如: invokegv file:///Users/Puer/.../script.groovy

注解

在Groovy脚本中有一个内建的变量 act , 他又一个叫做 getBean 的方法。通过这个方法你可以获得当前 OSGi 平台中所有的BlueprintContainer中的组件。他的输入参数时Bean或Service的id。 如果是使用Groovy文件的形式,注意文件的url格式。他是通过如下的正则表达式 file:\\/{2}(\\/[:\\w\\.]+)+ 进行验证的。并且路径中暂时不支持中文。

这个周末(23或24日)完成一个简单的录屏,来演示这个小工具的使用。

posted @ 2011-07-22 01:01 Jet Geng 阅读(3179) | 评论 (0)编辑 收藏

1 概述
Blueprint 使用手记 Jet Geng
July 10, 2011
Blueprint 是 OSGi Service Platform Enterprise Specification 标准的一 部分。很多最佳实践中也都推荐在应用程序中使用他。最近在项目中用他 来发布和应用服务。感觉效果不错。所以就有了这篇使用手记!欢迎各位 看官拍砖!
2 配置环境
我们在前期找到了两个 Blueprint 的实现:一个是 Apache 的 aries,另 外一个就是 Eclipse 的 Gemini。最后选择了 Gemini。做出这样的决定出于 两点考虑:
• Blueprint的标准就是由Spring提出。
• Gemini的初始代码由Srping所捐献。 下面我就简单介绍一下环境的配置过程:
• 从http://eclipse.org/gemini/ 下载 Gemini 的合适的版本。我们 采用的是 1.0.0M1。并解压到路径 A
• 从http://static.springsource.org/downloads/nightly/milestone-download. php下载 spring-osgi-2.0.0.M1-with-dependencies。并解压到路径 B。 他里面包括了 Gemini 所依赖的 bundle。说白了也就是 SpringFrame- work。
• Eclipse 中新建一个 Target Platform。把上述的路径 A和 B 加入到新 建的 Target Platform 中去。
• 选择新建的 Target Platform 为当前活动的 Platform。 3 启航
个人理解 Gemini 就是 OSGi 世界中的 IOC。既然是一个 IOC 框架,那 我们就从创建一个 Bean 开始吧!

3.1    创建一个 Bean 首先我们来看一下我们要存入 Container 中的 POJO。
Listing 1: POJOWillInContainer.java
package org.gunn.gemini.demo;
import org.slf4j.Logger; import org.slf4j.LoggerFactory; /**
* This pojo will create by blueprint container * 
@author Jet Geng * */
public class POJOWillInContainer { private Logger logger =
}
LoggerFactory.getLogger(POJOWillInContainer.
class); private String name ;
private String age;
public void setName(String name) { logger.info("the new name is:" + name); this.name = name;
}
public void setAge(String age) { logger.info("the new age value is:" + age); this.age = age;
}

这个超级简单的一个 POJO,我们如何通过 Gemini 来创建他呢?我们通过 一个简单的配置文件。具体如下。
Listing 2: pojoconfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
    
<bean id="myPOJO" class="org.gunn.gemini.demo.POJOWillInContainer" >
        
<property name="name" value="JetGeng"/>
        
<property name="age" value="32"/>
    
</bean>
</blueprint>

用过 spring 的兄弟,第一眼就能看明白这个配置文件说的是什么。其实就 是创建了一个 bean。到这里,我们所需要做的工作其实就已经完成了。下 面就可以通过 Debug 来启动了。
3.2    运行 Blueprint 容器 首先把 pojoconfig.xml 文件放到 project path/OSGi INF/blueprint 目录
下。或者在 MANiFEST.MF 文件中通过如下语句进行指定。 Blueprint-Bundle: config/account-data-context.xml, config/osgi-*.xml
更多内容参考http://www.eclipse.org/gemini/blueprint/documentation/ reference/1.0.0.RC1/html/app-deploy.html中的 8.2 Blueprint Manifest Configuration Comparison。好了,我们可以启动我们的应用程序了。为了 能够让 blueprint 顺利的跑起来,我们必须要把 blueprint 相关 bundle 以及 他所依赖的 bundle 都加入到运行时中。 按照上图配置后,点击运行。我们
Figure 1: Debug 配置

将在控制台得到如下内容。

控制台中的黑色行显示我们的 POJO 已经被 BlueprintContainer 创建

了,并且设定了相关属性。
.
这个部分的全部代码已经放到了 git://github.com/jetgeng/OSGi.git 中了。 感兴趣的筒子可以 down 下来玩玩。
posted @ 2011-07-10 11:06 Jet Geng 阅读(5099) | 评论 (4)编辑 收藏

用Graphviz显示树

缘起

前几天不知道那根筋搭错,又拿出了大学时候买的一本讲算法的书翻了起来。想起当年学习Tree的时候,看着数据结构凭空去想那颗倒着的树。那个叫做苦啊。所以就像有没有什么办法让Tree自己画出这样的结构图出来。

动手

既然想到了,就动手做把。因为以前用Graphviz画过一点mindmap,类图之类的小东西。让我一下子就想到了,我只要能从Tree结构中方便的输出成一个能绘制出对应树结构的Graphviz脚本就可以。这应该是代价最小的做法。 呵呵,废话不多说了。看看的Tree的代码吧!

 @Override
    
public String toString() {
        StringBuffer strValue 
= new StringBuffer();
        StringBuffer rout 
=  new StringBuffer("{rank=same ");
        
        
if(getLeftTree()  != null ) {
            strValue.append(root).append(ARROW).append( getLeftTree().getTreeNode()).append(
";\r").
                        append( getLeftTree());
            rout.append(getLeftTree().getTreeNode() ).append(ARROW).append(EXTEND).append(root);
      
        }
        
        strValue.append(EXTEND).append(root).append(
"[label=\"\",width=.1,style=invis];\r");
        strValue.append(root).append(ARROW).append(EXTEND).append(root).append(
"[style=invis];\r");
     
        
if(getRightTree() != null) {
            strValue.append(root).append(ARROW).append( getRightTree().getTreeNode()).append(
";\r").
            append( getRightTree());
       
            rout.append(ARROW).append(getRightTree().getTreeNode());
        }
        strValue.append(rout).append(
" [style=invis] } ;\r");
        
return strValue.toString();
    }

产生脚本的动作全部在这里完成了。我通过如下代码创建了一颗树

       ITree<Integer> tree = new TreeImpl<Integer>(6);   
        tree.addNode(
3);
        tree.addNode(
16);
        tree.addNode(
5);
        tree.addNode(
4);
        tree.addNode(
2);
        tree.addNode(
10);
        tree.addNode(
30);

最后得到的一副如下的图

呵呵,这样的话就可以随时查看树的结构了,我们所需要做的只是把object toString一下就可以。

附上一些文件

演示的录屏文件

完整的代码 

posted @ 2010-08-11 12:59 Jet Geng 阅读(3859) | 评论 (1)编辑 收藏

近来想了解一下关于网站建设方面的内容。自然而然的就找到了Drupal这个东西。刚开始没有发现他是多么的强大。抱着试试看的态度,

搭建了一个环境跑跑看。看完之后惊呼强大!他的强大来源于他的高度的可扩展,丰富的模块,主题。让你可以不写一行代码构建出一个不错的网站来。 看到这么强大的东西,就禁不住好奇往里看。于是找到了一些资料特与大家共享: 书籍:

  •  Using Drupal
  • Drupal 6 Attachment Views
  • Pro Drupal Development 悄悄的说一声,这几本书在itpub上都有下载。

视频:

还有两个很不错的网站。

上面提供了很多高质量的教学视频。让我这个初学者很快对drupal有个直观和深入的了解。

youtube.com上也有很多视频,有梯子的童鞋可以过去看看!

posted @ 2010-05-30 23:44 Jet Geng 阅读(1706) | 评论 (0)编辑 收藏


文中提到的代码castexception_src
编译好了包括不同的版本org.gunn.castexception.supplier插件文件为castexception_bin
posted @ 2010-05-14 19:15 Jet Geng 阅读(2781) | 评论 (6)编辑 收藏

问题

这两天在写一个小东西。这个小东西是一个大东西的一部分。其实也就是其中的一两个类。而这个大东西需要部署到一个特定的环境中去运行。所以有一堆的限制条 件,比如什么配置文件啊,包名,版本之类的什么东西。稍微有点差错就没有办法运行。需要正确得到这些东西需要一个很庞大且冗长的构建过程。而我写的也就是 两三个类,所以最直接的方式就是把我写的java 文件编译或的class 文件直接复制到jar文件中。 完成这样工作有好几中方式,最直接的方式就是纯手工打造


GraphViz image

PS: 这种方式费时费力,需要在不同的窗体间进行切换。例如我现在就在Eclipse、WinRaR和Windows资源管理器间切换。

解决过程

如何避免这个过程呢,尽量不用人来参与其中。这个肯定就是让一个小程序来把这几个动作连接起来。而且还要能够方便变动。比如我现在不想往a.jar 里面copy了。我想向b.jar 中复制了。所以就想到了脚本。对让脚本来完成这样的事情。第一反应想到的是ant

Ant 我的主角

  Ant 是 何须人,就不用我多说了。其实我了解也不多,只是知道这个小蚂蚁蛮力超大。下面就着手解决问题。第一反应就是找到一个直接copy的任务,把 fileset中的文件复制到jar文件中。但是遗憾的是我没有能够找到这样一个Task.这个时候我的思维陷入了困境。下面该怎么办?

困境

没有现成的东西,没有现成的能一步完成的东西?如何是好? 我是程序员,所以我我自己可以写一个task来满足这样的需求啊。对啊,我可以自己写的!正当我为这个想法兴奋不已时,正卷起袖子准备“大干”的时候。突然想起某人说过 不要重新造轮子! 。所以就追问了我自己一句: 角处会有什么呢?

我的拐角

既然Ant有蛮力,我可否利用一下他的蛮力呢?通过如下的这么一个流程来达到我的目的。


GraphViz image

这里用了一个temp文件夹作为中转,先解压,copy需要的文件,最后jar一下获得最后的更新好的jar。 最终获得了如下的build.xml

<target name="prepare">
                
<mkdir dir="${temp_dir}"/>
        
</target>
        
        
<target name="build" depends="prepare">
                
<echo message="unzip">Uzip Jar file</echo>
                
<unjar dest="${temp_dir}" src="${comp_plugin}/${contain_plugin}">
                
</unjar>
                
<copy todir="${temp_dir}">
                        
<fileset dir="./bin">
                                
                        
</fileset>
                
</copy>
                
<jar update="true"
                        destfile
="c:/${contain_plugin}" 
                        basedir
="${temp_dir}" >
                
</jar>
        
</target>
  

调整的过程

看上去,所有问题都解决了。但是偏偏在使用的时候遇到了小问题。我的jar包是要在osgi环境下工作的。所以特别依赖MANIFEST.MF文件。偏偏jar 这个任务默认情况下会生成一个默认的MANIFEST.MF文件。如果任由他胡来的话,就全虾米了。所以要稍微调整一下。


<jar update="true"
                        destfile
="c:/${contain_plugin}" 
                        basedir
="${temp_dir}" 
                        manifest
="${temp_dir}/META-INF/MANIFEST.MF">
</jar>
 

这样就可以了。大功告成!!

posted @ 2009-11-26 18:07 Jet Geng 阅读(2501) | 评论 (3)编辑 收藏

在我们创建领域模型前,我们有必要了解一下我们的模型用来表达什么内容。 所以我就先解释一下在这个系列文章中要实现应用。 假设Eclipse组织邀请你编写一个让他们管理贡献者和项目的应用程序。

我们需要创建一个模型来表达客户提供的信息。他们有可能如下图。

让我们进一步的看看这个模型。

Fundation

fundation是这个模型的根,他拥有两个列表属性。

projects: 像EMF,Techonlogy,Platform这样的顶级项目。
persons: 参加一个或多个项目的人。
Project

Eclipse项目拥有很多属性,比如项目开始和结束时间、项目的主页的url等等。下面列出我们最感兴趣的。

subprojects: 一个项目可以拥有多个子项目。子项目本身也可以拥有多个子项目。
parent: 项目有一个父亲(除了顶级项目外)。这就意味着项目和子项目(project-subproject)的关系是一个双向的关系。
projectleads 一个项目有多个项目领导人。
committers 一个项目可以拥有多个贡献者。
CommitterShip

当一个用户成为一个项目的贡献者(Committer)时,这就建立了一个committership。他拥有一个开始时间和结束时间。另外我们还要记录下下面的属性。

project: 和committership相关的项目。项目和committership是一个双向的关系。
person: 参加项目的人。
Person

贡献者或项目领导人的信息。我们关系的信息如下:

committerships: 用于保存和人相关的所有的committerships.这说明人和committership是一个双向关系。

下面这张类图给出了关于上面模型的全貌。

正如你所看到的,我把许多关系设成了双向关系。 As you noticed I modeled many of the relations as bidirectional relations. 这个并不是严格要求所有地方都要这样,因为有的地方可以通过eComtainer来获取他的父亲。就像project-subproject一样。 但是包含关系(containment relationship)在使用databinding的情况下就不太合适了。因为从子到父亲时没有对应feature,只能通过调用eContainer()方法来获得。 EMF提供了一个编辑器来创建你的Ecore-Model并把它保存成XMI格式。我们可以用它来创建测试数据。下图就是一个例子。

posted @ 2009-11-07 22:41 Jet Geng 阅读(2087) | 评论 (0)编辑 收藏

1.译序

在学习EMF-Databinding的时候发现了Tom Schindl的博客。他的博客中有一个关于EMF Databinding的专题。感觉很不多。想尝试着翻译一下。 那么Tom Schindl是何许人也?他是JFace项目的一个Contributor,在2007年Eclipse Zone 就曾经采访过他。 所以称他为EMF Databinding的专家一点也不过分。

Note

原文为路径为http://tomsondev.bestsolution.at/2009/06/06/galileo-improved-emf-databinding-support/

2. 原文

我很高兴的宣布在Eclipse-Galileo中EMF-2.5已经开始支持新的Eclipse-Databinding API了。荣誉归Matthew Hall,他审查我的代码,帮我整理支撑部分并且整理文档(详细内容在bug 262160 中)

几周前我成为了EMF项目的捐献者,现在我负责Databinding对EMF的支持模块。我将尽力修正API中的问题,回答Newsgroup中的问题。

请允许我在介绍这个API的优点以及如何使用它之前声明一点:这个API还处于过渡期,他可能会有一些细微的变化。不过我们将会详细说明变化的部分。

我将用一个系列文章来展现这个新的EMF-Databinding:

第一部分:创建领域模型
第二部分:介绍新的Properties API
第三部分:用EMF-Databinding绑定到TreeViewer
第四部分:在master-detail模式中使用Properties API
第五部分:用EMF-Databinding绑定到TableViewer
第六部分:Write your own Property for unsupport Widget-Types
第七部分:Make the storage system plugable

为了让你快速进入EMF-Databinding中,我在前几天做了一个例子。

所有代码都是基于EPL协议,你可以在从Eclipse-CVS 处获得。

posted @ 2009-11-07 22:39 Jet Geng 阅读(2085) | 评论 (0)编辑 收藏

在看《卓有成效的程序员》 迷你书的时候,发现gant这个小东西。一下子就被他镇住了。心想原来还可以通过这种方式来使用ant。

随后在ibm的技术网站上找到了用Gant构建软件 这个在线教程。简单的过了一下,发现还真的好用。还有因为工作原因经常需要写一点测试用的web service。而我对这个又不是特别属性,想用Java来写有怕太麻烦。所以想找一找有没有什么动态语言很方便的能够实现web service(其实重点是找python的)。最后还是发现GroovyWS. 通过这样两个小东西,我发现groovy真的很不错。特别是对于java程序员来说。所以准备系统的学习一下他。特此记下。

posted @ 2009-11-07 22:38 Jet Geng 阅读(290) | 评论 (0)编辑 收藏

删除空行

g/^\s*$/d                  : delete all blank lines

 

这个里面使用了“:g”命令,Google了一下,找到了如下描述:

:g is something very old and which is very powerful. I just wanted to illustrate the use of it
with some examples. Hope, it will be useful for someone.
Brief explanation for ":g"
-------------------------
Syntax is:
    :[range]:g/<pattern>/[cmd]
You can think the working as, for the range (default whole file), execute
the colon command(ex) "cmd" for the lines matching <pattern>. Also, for all
lines that matched the pattern, "." is set to that particular line (for
certain commands if line is not specified "." (current line) is assumed).
Some examples
-------------
Display context (5 lines) for all occurences of a pattern
    :g/<pattern>/z#.5
    :g/<pattern>/z#.5|echo "=========="
    << same as first, but with some beautification >>
Delete all lines matching a pattern
    :g/<pattern>/d
Delete all blank lines (just an example for above)
    :g/^\s*$/d
Double space the file
    :g/^/pu =\"\n\"
    :g/^/pu _
    << the above one also works >>
Copy all lines matching a pattern to end of file
    :g/<pattern>/t$
Yank all lines matching a pattern to register 'a'
    0"ay0:g/<pattern>/y A
Increment the number items from current line to end-of-document by one
    :.,$g/^\d/exe "normal! \<c-a>"
Comment (C) lines containing "DEBUG" statements
    g/^\s*DEBUG/exe "norm! I/* \<Esc>A */\<Esc>"
A Reverse lookup for records
(eg: An address book, with Name on start-of-line and fields after a space)
    :g/<patern>?^\w?p               "if only name is interested
    :g/<patern>/ka|?^\w?p|'ap       "if name and the lookup-line is interested
    :g/<patern>/?^\w?|+,/^[^ ]/-1p  "if entire record is interested
Reverse a file (just to show the power of 'g')
    :g/^/m0
Foot note 1: use :v to negate the search pattern
Foot note 2: Some explanation of commonly used commands with :g
:2,8co15 => Copy lines 2 through 8 after line 15
:4,15t$  => Copy linesa 4 through 15 towards end of document (t == co)
    :-t$  => Copy previous line to end of document
     :m0  => Move current line to the top of the document
:.,+3m$-1 => Move current line through cur-line+3 to the last but one line
             of the document
Foot note 3: Commands used with :g are ex commands, so a help search should
             be,
                :help :<help-topic>
                eg. :help :k

尝试翻译如下

:g是一个非常老且很强的的命令。我只想通过一些例子来演示他的用法。希望对被人有用。

“:g”的概述

         语法::[rang]:g/<pattern>/[cmd]

你可以认为他是这么工作,在特定的范围内([rang]确定,默认是整个文件)。他逐行逐行的用<pattern>去匹配,如果匹配成功就执行 冒号命令 (“cmd”来指定)。另外,如果<pattern>匹配所有行,那么只有对当前行执行 冒号命令。

 

今后会不断更新……

 

--------------------------

:%s/^\(.*\)\n\1/\1$/        : 删除重复行 # 非贪婪匹配,\{-}

一会来分析

posted @ 2008-05-28 10:55 Jet Geng 阅读(2518) | 评论 (3)编辑 收藏

今天遇到了点事情,无法入眠。起来写点小东西吧,突然想起前几天就说的好好了解一下java中的Date这件事情来。刚好就这么顺手做了吧!

 

首先java.sql.Date是java.util.Date的一个子类。他拥有java.sql.Date的所有功能,他只是做了点扩展。这点扩展是为了让JDBC能够识别成date类型。就是这样子的。

image

其实也真的没什么好写的。就这样吧,作为一个记录!

posted @ 2008-05-27 00:43 Jet Geng 阅读(545) | 评论 (1)编辑 收藏

       Birt这个项目开始已经很久了。先前一直没有使用表报的需求,所以也就没有对这个项目做太多的关注。就在前一段时间突然有了这一方面的需求,所以就开始在网上疯狂的Google和Birt相关的信息。因为这个项目开始时间挺长了,而且越来越成熟。所以和他相关的资料挺多。efa在他的《[JAVA - BIRT]Birt 学习资料》已经给出了很多内容。

      除了这些内容外我还找到了三本书:

  1. BIRT: A Field Guide to Reporting
  2. Integrating and Extending BIRT
  3. Packt.Publishing.Practical.Data.Analysis.and.Reporting.with.BIRT

     第一本和第二本是在是基于 Birt 2.1。

      第三本书是基于Birt 2.2

    有了这些东西基本就可以上路了。但是我又一想,如果有点例子就更好了。例子肯定是有的。官方就有,还等什么呢还不赶紧去拿。

 

birt

到里面随便找吧。肯定有你合适的。

下面要做的事情就是分析好你的需求,好好用birt来表现你的内容了。

posted @ 2008-04-04 10:01 Jet Geng 阅读(1249) | 评论 (0)编辑 收藏

关于《Developing Eclipse/OSGi Web Applications Part》一文中的例子

近来看看点OSGIWeb开发中的应用。看到这个方面的东西肯定会搜到EclipseZone上面的一篇文章,他叫《Developing Eclipse/OSGI Web Application》。说实话这个文章写的真的没说的,浅入浅出的同时还给你真正带来不少好东西。他的所有的内容是围绕着一个叫Rsp的例子进行的。这个例子在http://sourceforge.net/project/showfiles.php?group_id=122298 处可以下载到。


这里我下载了rspDemo-0.2.zip这个包。按照要求把包打开,并且运行。果然可以运行,并且能够得到文中所说的结果。

下面我们就来看看解压后的文件夹:

这个里面不光包括了示例代码还包含了一个tomcat-5.5.15生怕被人机器上没有装tomcat。好了,把我自己的eclipseworkspace设置成c:\rsp\workspace。这样我就得到了一个如下图的工作界面:

这个时候我不想使用rsp中自己带的那个tomcat,我想自己已经有的tomcat。就在这个时候我遇到问题了。什么问题呢,我们来看看启动时的log

严重: Servlet.service() for servlet jsp threw exception

org.apache.jasper.JasperException: The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml or the jar files deployed with this application

    很明显是没有找到urihttp://java.sun.com/jsp/jstl/core tld文件。不对啊,这个应该都是在web应用程序里面的啊。但是他自己带的tomcat就可以。肯定是他自己加了。我找了好大一会儿终于在C:\rsp\apache-tomcat-5.5.15\common\lib多出两个包他们分别是jstl.jarstandard.jar。查看了一下standard.jar所有真相大白。他包含了一个c.tld的文件。其中有这么一段

<description>JSTL 1.1 core library</description>

<display-name>JSTL core</display-name>

<tlib-version>1.1</tlib-version>

<short-name>c</short-name>

<uri>http://java.sun.com/jsp/jstl/core</uri>

好了,把这两个包放入到我自己的tomcat中,所有问题都解决了。终于顺畅的跑起来了。


posted @ 2008-03-15 15:33 Jet Geng 阅读(2494) | 评论 (1)编辑 收藏

问题一:

问:项目图标报错,Problems 试图有一条错误显示“Java compiler level does not match the version of the installed Java project facet.”

答:这个是因为Facted Project中的Java版本设定与项目的Java版本设定不一致。

Drawing 1: Modify: Modify Faceted Project中所示,这个时候项目的Java的版本为5.0。如果项目的Java Compiler的设置如Drawing 2: Java C: Java Compiler中所示的设置。就是会出现问题中所述的错误。修改的方式很简单,只要统一一下他们的设置。让他们保持一致就OK了。


posted @ 2007-10-15 14:26 Jet Geng 阅读(3907) | 评论 (2)编辑 收藏

使用DTP时遇到一个很奇怪的问题。

我所使用的DTP的版本是dtp-sdk_1.0_200612211。我通过Data Source Explorer来浏览数据库是发现有的字段的类型不能正确显示。


这个数据库是Mysql 5.0.

这个数据表在Navicat中的设计视图如下图。


这种问题不光出现在mysql数据库中,在oracle 10g的数据库中我也发现了类似的情况。

发现他不能正常的显示Clob和Blob这两种类型。



在Sql plus中这个表的描述为:


知道怎么回事的兄弟们,帮忙告诉我一声。先谢谢了。

posted @ 2007-06-22 14:39 Jet Geng 阅读(656) | 评论 (2)编辑 收藏

这几天在resin跑一个taglibcommon-controls http://www.common-controls.com/en/index.php)库。发现很多东西不能用。下图中的菜单全部变成了“logout”。其他的全部没有了。


这个页面在tomcat下跑起来的效果是:

怎么会是这样。看上去是不是很奇怪啊。

后来查看了一下cc-samples\WEB-INF\work\_jsp\_jsp\_template下的_header__jsp.java

发现

com.cc.framework.taglib.menu.MenuItemTag这个类只被创建了一次。而且在重复使用。

if (_jsp_MenuItemTag_3 == null) {

        _jsp_MenuItemTag_3 = new com.cc.framework.taglib.menu.MenuItemTag();

        _jsp_MenuItemTag_3.setPageContext(pageContext);

        _jsp_MenuItemTag_3.setParent((javax.servlet.jsp.tagext.Tag) _jsp_MenuTag_2);

}

于是我就在猜想啊向com.cc.framework.taglib.menu.MenuTag这个类的实例中添加了那么多MenuItem肯定就只加了这么一个实例了。所以在最后显示的只显示出最后设置的参数了。

 

最后查看有一个仁兄也遭遇了类是的情况。也用blog记录下来了。下面的话就是他的结论:

于同名标签,引用10,Tomcat就会创建10个方法和标签对象来做对应的处理。而Resin只会创建1个对应的标签实例,如果后面再 引用,则不会创建新的,只操纵唯一的一个实例。所以在标签的逻辑处理中,要注意属性释放和还原的情况。我犯的错误就是因为其中的一个属性一直保存在该实例 中并没有销毁,导致后面再处理的时候发生冲突。

 

http://b0r0j0.blogbus.com/logs/4028462.html


posted @ 2007-04-05 16:36 Jet Geng 阅读(1498) | 评论 (1)编辑 收藏

今天终于把solaris的环境变量搞明白了。
Solaris中设置环境变量和你当前采用的Shell有关,不同的Shell需要写入到不同的文件中。

如果你是Bourne Shell
PATH=$PATH:/usr/bin; export PATH
环境文件为.profile

如果你是 C shell
变量设置
路径变量:set path=($path /usr/bin)
 环境文件
.login .cshrc

这里有个问题是我如何能够知道我自己用的是那种类型的shell呢?
有办法 使用cat /etc/passwd

solaris-path.jpg

你会得到如上图所示的内容,看看你自己的那一行。在上面的文件中,我是有下划线的那一行。后面的/bin/sh就表示我使用的是Bourne Shell。我只需要按照那个来设置就好了。

 

有一点就是如果PATH已经被export过了,那么你就可以把“export PATH ”这一段省略调了。

solaris 9上跑通过了。
在solaris上我还完全是一个新手,如果有什么说的不对的地方欢迎指正。谢谢了先。
posted @ 2007-03-26 16:12 Jet Geng 阅读(4003) | 评论 (2)编辑 收藏

今天看到了Eclipse AspectJ这本书,小试了一下这个东西还真的不错。
posted @ 2007-03-06 14:48 Jet Geng 阅读(466) | 评论 (0)编辑 收藏

 

gef项目中连线一直扮演这个不可或缺的角色。碰巧前段时间有个机会好好的看了这个部分的内容。下面就把我的一点点认识和大家分享。

首先要在模型上支持,能够保存连接的信息。对于不同的项目有不同的要求。我们通过两个例子就可以看出这一点来。

1http://www13.plala.or.jp/observe/GEF/示例中的GEF6.zip (下面称这个例子为HelloWold

运行的结果入下图所示:

hellwoui.jpg

它的模型可以使用如下的类图来表示:

LineConnectionModel-i.jpg

用来描述Connection的分别是LineConnectionModelArrowConnectionModel这两个类。这两个类的父类和图形模型(HellowModel)相关。

2IBM红皮书中的GEF范例(下面称这个例子为workflow)

运行效果如下图:

gefrun.jpg

他的模型可用下面的类图描述:

gefredbook.jpg

其实连接的模型应该很简单,他只要能保存他的两端的对象就好了。图形模型(如HelloWold中的HelloModel)能够保持与他相关连的连接(HelloWold中的LineConnectionModelArrowConnectionModel)。

看完了Model,我们下面就可以看看EditPart部分了。

要看EditPart当然是要看最关键的了。也就是和连接直接关联的EditPart了。分别察看了和连接相关的EditPart,发现他们都会实现一个叫org.eclipse.gef.NodeEditPart的接口。如下图所示:

ShapeEditPart-a.jpg

nodeEditPart中有四个方法需要实现。通过这个四个方法的名字就可以看出他们和Anchor2密切相关。下面就来看看这几个方法的具体功能:

ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection);

当需要画连接的时候,通过这个方法获取连接的源锚点。不管这个锚点在什么位置,他取得以后直接就用它作为源点了。

ConnectionAnchor getSourceConnectionAnchor(Request request);

当在准备创建连接的时候,通过Request来获取新连接的源锚点。

另外的两个就不再啰嗦了。是为了获得目标的锚点。


但是我们肯定看到了HelloWoldWorkflow中的连接有点不一样。HelloWold中直接是图元上的,而workflow是通过连接基本图元上面的一个子图元而连接的。简单来说就是他们连接的anchor有点不一样,这样就会出现执行结果的不同。

下面来看看他们到底是怎么实现的。根据上面提到的。锚点的获取是通过getSourceConnectionAnchorgetTargetConnectionAnchor方法来获取的。我们只需要好好比对一下他们这几个方法的不同就可以了。

HelloWold中的getSourceConnectionAnchor

public ConnectionAnchor getSourceConnectionAnchor(Request request) {

returnnew ChopboxAnchor(getFigure());

}

这里就简单的创建一个 ChopboxAnchor 就好了。这个就可以直接连到该Figure上了。

workflow中这个情况稍微有一点复杂了。先不说,还是看看他的 getSourceConnectionAnchor 是怎么实现的。

public ConnectionAnchor getSourceConnectionAnchor(

ConnectionEditPart connection) {

Connection edge = (Connection) connection.getModel();

return getNodeFigure().getConnectionAnchor(edge.getSource().getName());

}


/**

*returnsananchorgivenitsname

*

*@paramportNamenameoftheanchor

*@returntheanchorwiththename<code>portName</code>

*/

public ConnectionAnchor getConnectionAnchor(String portName) {

return (ConnectionAnchor)connectionAnchors.get( portName );

}


protected Hashtable connectionAnchors = new Hashtable(7);


/**

*Addaninputportanditsanchor

*

*@paramportName

*uniquenametorefertotheport

*/

publicvoid addInput(String portName) {

InputPortFigure inputPort = new InputPortFigure();

add(inputPort);


PortConnectionAnchor anchor = new PortConnectionAnchor(inputPort);

getTargetConnectionAnchors().add(anchor);

connectionAnchors.put(portName, anchor);

}


通过这几个方法可以看出它是在添加Input时候就创建好了一个和PortFigure 相关Anchor并把它保存起来。在要用的时候就把它取出来。这样就搞定了。

具体的可以参考这两个例子的代码。好了,打完收工。


参考文档

IBM 红皮书

1荒野困兽(老脸归来)’blog

2GEF 进阶,第一部分: Anchor


posted @ 2007-01-08 17:09 Jet Geng 阅读(2888) | 评论 (1)编辑 收藏