2006-12-14

xslt

XSLT是xsl的一部分, 用来表示输出template.它的输入是xml格式的数据, 通过xpath浏览, 如果遇到满足template的matcher就产生templa
te:

<xsl:template match="/book/author">
</xsl:template>

match就是xpath表达式, 它会把输入xml数据中所有满足这个expression的items全传到template里面来, 在里面可以进行一些控制流, 如foreach, if-else等.
cocoon处理的核心就是xml, 而xslt是标准的处理手段
参考 : link

--
It's Hard to Define, But I Know it When I See it…

jmx architecture

jmx强调2个方面: management和remote.  app, device, service, resource 都是可以被管理的instrumentation. MBean通过agent来管理它所代表的instrumentation. MBean Server也是一个agent(现在明白了,Server也是个instrumentation,  以前看到的时候总有些糊涂 :(  ).

--
It's Hard to Define, But I Know it When I See it…

2006-12-08

JET--生成java代码的模板

跟JSP差不多的东西, 它根据你传进来的参数通过模板方法生成结果数据.为什么会有这个能力呢? 因为它把你定义的template转成java对象. 有2个重要的概念:
  1. argument, 不仅仅是字符串, 可以是任何java对象, 是与template打交道的入口
  2. generate(), 实际上这个方法的内容就是你的模板, argument参数是传给它的.
比如我有个模板定义如下:
<%@ jet package="hello" class="HelloWorldTemplate" %>
hello <%=argument%>!
那么保存后会自动生成HelloWorldTemplate类, 调用看看:
HelloWorldTemplate template = new HelloWorldTemplate();
String result = template.generate("lakemove");
System.out.println(result);
输出结果为:
hello lakemove!

除了这, 还有模板的模板--skeleton, 比如你想定义temlate要继承什么方法, generate的返回类型等.

具体参考 : link
--
It's Hard to Define, But I Know it When I See it…

2006-12-07

mysql数据库备份

查了半天doc也没找到, 有个例子,不过产生出来的是一大堆文件, 我只想一个数据库一个文件, 而不是一个表...后来google一下就全出来了, 晕死....

mysqldump -uroot -ppassword --database mydb > mydbfile.sql

还有一种是
mysql -uroot -ppassword --database mydb > mydbfile.sql
不过好像不管用,它会backup整个mysql所有数据库.

link, link2

--
It's Hard to Define, But I Know it When I See it…

2006-12-06

JVM集群

谈java通常说的集群基本都是server上的集群, 也就是app级别的.比如tomcat. 性能差异来自session.setAttribute的处理策略. 今天这个terracotta 就比较强了, 看看, 居然能做到JVM级别的cluster, POJO也可以在集群环境中应用而不必须实现Serializable.而且不用修改代码.
还不太清楚它具体是如何实现的, 估计是比较龌龊的策略(优美的别人也能想到, 在google上查, 找不到alternative).今天把代码下载回来了, 研究去....

--
It's Hard to Define, But I Know it When I See it…

test

  //actions
  protected Action backAction = null;
  protected Action forwardAction = null;
  protected Action refreshAction = null;
  protected Action stopAction = null;
  protected Action goAction = null;


--
It's Hard to Define, But I Know it When I See it…

2006-11-20

MapList

一直希望有个MapList这样的东西, 有k/v对,但是却是list形式存放的,可以排序.

List<String, String> maplist = new ArrayList<String, String>();

找过.没找到.今天写程序就突然想起来了,其实挺简单:

List<String[]> maplist = new ArrayList<String[]>();
String[] item = new String[2];

然后就是排序:

Arrays.sort(maplist, new Comparator(String[])
    {
  public int compare(String[] src, String des)
  {
    return src[0].compareTo(des[0]);
  }
    });

--
It's Hard to Define, But I Know it When I See it…

2006-11-14

xpath用法

有如下的xml文件nodes.xml :
<library>
  <book sum="22">helloworld
  </book>
</library>

提取 "helloworld" 这个字符串 :
        String filePath = "nodes.xml";
        InputSource inputSource = new InputSource(filePath);
        XPath xpath = XPathFactory.newInstance().newXPath();
        String expression = "/library/book[@sum='22']";
        String nodes = xpath.evaluate (expression, inputSource);

参考 : xpath语法, xpath validation , easy and efficient xml

--
It's Hard to Define, But I Know it When I See it…

2006-11-10

nsIHTMLEditor的获取

代码大概是这样的:

        final nsIWebBrowser webBrowser = browser.getWebBrowser();
        nsIInterfaceRequestor requestor = (nsIInterfaceRequestor) webBrowser.queryInterface(nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID );
        final nsIEditingSession session = (nsIEditingSession)requestor.getInterface(nsIEditingSession.NS_IEDITINGSESSION_IID);
        nsIDOMWindow window = webBrowser.getContentDOMWindow();
        session.makeWindowEditable (window, null, true);
        nsIEditor editor = session.getEditorForWindow(window);
        htmlEditor = (nsIHTMLEditor) editor.queryInterface(nsIHTMLEditor.NS_IHTMLEDITOR_IID);

本来是把他加在mozEditor的createPartControl里的, 这样运行出来editor一直是null.后来想到editor的获取应该在browser加载完document之后才能进行的罢? 于是就把代码加到ProgressListener的onCompleted()里面.运行,OK.
我觉得那个session应该也是在这个里面的,不过它在前面的代码里也能正确获取.
browser的加载一直都是异步的,新建线程?以前好像也有过一次因为加载顺序的原因而导致的错误.嗯..幸亏有个onCompleted方法

--
It's Hard to Define, But I Know it When I See it…

2006-11-07

比较2种技术

javaeye上看到的,感觉分类还挺全面的:
- Cost, including Developing, Migration, Maintenance, Fee, Performance Tuning etc.
- Tool Support, including what tool/component could be used etc.
- Performance
- Extensibility
- Integrability
- Technical Support, including vendor support, 3d support
- Technical Resources
- Stability
- Challenge
- Technical Trend
- Migration
- Special Language Features
- Security
- Applying domain
- Technical Background

2006-11-03

原来这样也可以写blog

通过gmail发送邮件到lakemove.____@blogger.com.真是个不错的想法 :D

--
It's Hard to Define, But I Know it When I See it…

加载插件

俺这有三个plugin projects:
org.eclipse.atf.mozilla.ide.core
org.eclipse.atf.mozilla.ide.ui
org.jbpm.ui
其中org.jbpm.ui依赖于前2个plugins. 构建工程org.jbpm.ui不成功,然后在configure buildpath里把其它2个plugins引用进来,OK. 以RCP方式运行org.jbpm.ui的时候,报错说找不到那两个plugins里的类,郁闷了好久,后来在plugin.xml里把对那2个plugins 的depedencies加进来就OK了.从buildpath里删除之前加的内容也可以构建了.开始没仔细考虑这个问题,只胡乱的试.今天看下osgi的规范,感觉类加载还是满重要的方面,然后就从这个角度解决了.

2006-10-25

使用JAXB

看着xml格式的数据,就在想能不能自动把它变成java对象呢? 找了下,很多的说,就选了JAXB(java api for xml binding).
javaEE5里面有sample,在${javaee.home}/samples/javaee5/webservices/simple-jaxb下面.直接ant就可以了.不过俺是把它放到eclipse里,碰到几个问题:
1.${basedir}属性被eclipse覆盖了,就是说在build.xml定义的basedir无效.
2.xsd定义的时候根elements需要与其子element连接起来,在types页那个不管用.
使用过程为:
1.写个dtd
2.生成javabeans
3.提供一个顺从dtd的xml文件,把它传给JAXBContext.嗯...可以直接使用了.

2006-10-20

接触rails

看10月份的程序员杂志,又见rails,心里痒.就试了下.

先是熟悉了下语法.挺猛的啊.简单且强大.

不过到rails的时候就特麻烦了.
去配置apache和fastcgi,整了半天,也没出个眉目.估计到现象fastcgi也没装上,因为页面显示好慢好慢.后来才发现rails自带了一个webserver
ruby script/server
就可以启动了.日.发现一点不好就是连数据库它可能进行缓存了.所以修改database.yml的时候它不起变化.就一直报错.用apache就没那情况,不过速度N慢N慢.比webrick慢很多.
连数据库时也挺郁闷的,用root账户连不了,老报错:
Lost connection to MySQL server during query: SHOW FIELDS FROM ...
后来新建立个用户就连进去了.
w:\>ruby script/generate model category
w:\>ruby script/generate controller category
class CategoryController < ApplicationController
model :category
scaffold :category
end
然后打开http://localhost/category
丫的真是简单.靠

2006-10-10

垃圾问题

dbdesigner老连不上数据库.试了N次.后来在网上查到:link
只要重置一下密码就可以了:
mysql>SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('newpwd');
真的是郁闷了.连上后试用了下.感觉也不太好,不稳定,老出错,看样子免费的还是不行啊

2006-09-27

json是什么样的

var MyJson=
{
  name:"myjson",
  description:"it is my json",
  display:function(arg){
    alert(arg);
  }
};

MyJson.display("json很简单");
link


powered by performancing firefox

2006-09-26

判断myfunc是否存在

判断myfunc是否存在

function myfunc(){
alert("helloworld");
}

try{
if(myfunc)myfunc();
}catch(e)
{alert("exception");}

2006-09-20

问题


  • 两个完全相同的类,JVM会如何加载呢?

    同时加,还是随机性的选择一个,抑或根据版本号选择版本较高的?

  • 如果两个类只是版本不同,JVM又会如何加载呢?

    在tomcat启动的时候,如果你的webapp里有较低版本的servlet-api.jar,会自动报告说版本过低然后不再加载它.但是,这可能只是jar....

getResourceAsStream

getClassLoader().getResourceAsStream && .getResourceAsStream()


package jay.home.test.comm;

import static org.junit.Assert.*;

import java.io.InputStream;
import jay.home.test.dbunit.DBUnitUsage;
import org.junit.Test;

/**
* @author Jay
* @since 2006-9-20 下午12:02:15
*/
public class GetResourceAsStream
{
@Test
public void getResourceByClass()throws Exception
{
// 如果不是在同一目录下,不可访问到
InputStream stream2 = DBUnitUsage.class.getResourceAsStream("resource.file");
assertNull(stream2);
// 可以访问,需要加全限定名
InputStream stream3 = DBUnitUsage.class.getResourceAsStream("/jay/home/test/comm/resource.file");
assertNotNull(stream3);
// 可以访问,如果在同一个目录下就可以直接访问
InputStream stream4 = GetResourceAsStream.class.getResourceAsStream("resource.file");
assertNotNull(stream4);
}

@Test
public void getResourceByClassLoader() throws Exception
{
ClassLoader loader = GetResourceAsStream.class.getClassLoader();

InputStream stream1 = loader.getResourceAsStream("resource.file");
assertNull(stream1);
// 可以访问,加包名
InputStream stream2 = loader.getResourceAsStream("jay/home/test/comm/resource.file");
assertNotNull(stream2);
// 不可以访问,不需要最前的/
InputStream stream3 = loader.getResourceAsStream("/jay/home/test/comm/resource.file");
assertNull(stream3);
}
}

2006-09-19

运行applet

以前一直以为网页内的applet需要用sun的activex才能运行,今天试了一手,原来这样也可以的:

d:/>appletviewer http://www.meterware.com/evdemo/index.html

看来,虽然麻烦,以后在重装系统的时候真的不需要重装JDK了

2006-09-18

Registry vs. Repository

A registry is a list of items with pointers for where to find the items, like the index on a database table or the card catalog for a library. A repository stores the actual items, like a database table itself or a library's shelves of books. If you lose a registry, the items still exist; you just may need to reindex them. If you lose a repository, the items are gone.

2006-09-05

布局

GEF的布局全仰仗org.eclipse.draw2d下的布局类,gef有种挺迷惑人的LayoutEditPolicy,其实它跟布局没关联,是用来产生command的:
public Command getCommand();
像什么getCreateCommand()、getDeleteCommand()等都是由它统一送出去的。
如果硬要说有什么关系的话,那么就是command所接收的context是LayoutEditPolicy从Layout等地方获取的。Layout准确得应该叫做是LayoutManager,有个核心方法大概表达的这个意思:
public void layout(IFigure parent)
{
List children = parent.getChildren();
for(IFigure item: children)item.setBounds(/**new Rectangle(...)*/);
}
它会管理其属下的Figure,当放一个元素到Figure pane的时候会自动调用pane的layout方法来重新布局。

static变量生存期

formEditor有一个奇怪的现象:
第一次打开它运行正常,比如创建新element等操作皆可。但是你把这个editor关闭然后再打开就会出问题,图形化的操作再不会产生反应了,model的数据也不再有变化。后来才发现,原来是在段代码出错:
private static IDOMDocument document = DocumentTransferer.getDocument();
把static去掉就OK了,其实就是一static变量生存期的问题。

java.util.Timer vs javax.swing.Timer

javax.swing.Timer.start()这个方法跟Thread.start()的方法含义是不一样的。前者的作用是把这个timer放到一个TimerQueue里去。这个TimerQueue是一个独立的进程,可以循环执行它所管辖的timer的post方法,post的意思就是这个timer到期了,可以通知以使事件发生。所以,如果想让你注册进来的actionlistener执行的话需要的不是timer.start(), 而是timer.post(),但是你不会有这个执行权利,因为它的访问权限是package。
你可能想了,那我能不能新建立一个thread来执行TimerQueue呢?也不可以。同样受访问权限限制。所以,惟一可能的办法就是把它放到swing的运行环境中,让swing来维护这个TimerQueue:
//javax.swing.Timer
public class SwingTimer extends JFrame
{
private ActionListener listener = new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("^^^^^^^^^^^");
}
};

public SwingTimer(){
super();
new Timer(1000, listener).start();
}

public static void main(String[] args){
//怪事,如果不设visible或设为false就不会循环执行,闷!
new SwingTimer().setVisible(true);
}
}

或者,你找的是这个东西:
//java.util.Timer
public static void main(String[] args)
{
TimerTask task = new TimerTask(){
public void run(){
System.out.println("^^^^^^^^^^");
}
};
Timer timer = new Timer();
//0millisecond后开始执行,每1000milliseconds执行一次
timer.schedule(task, 0, 1000);
}

2006-09-02

正则表达式的应用

最近有点喜欢帮人了:)

问题:
有一个文本文件如下

A,1
A,2
A,3
B,4
B,5
C,6
C,7
C,8

每行有两个元素,以逗号分隔,例如(A和1),文件的行数未知第一个元素都是连续相同的(如AAABBCCC),没有混乱现象(如AABABCCC)逐行读这个文件需要要把第一个元素相同的第二元素抽出来,放在一个新new出来的ArrayList里面例如读前面三行,第一个元素都是A,那么就new一个ArrayList,把第二元素1,2,3放进去然后接着读,第一个元素变成B了,这个时候需要重新new一个新的ArrayList,把第二元素4,5放进去再读,第一个元素变成C,再new一个新的ArrayList,把第二元素6,7,8放进去
请教算法,谢谢了!

解决

//这个字符串代表你的文件内容
String input = "A,1\nA,2\nA,3\nB,1\nB,2\nB,3\nB,4";
public void testCSDN()
{
Pattern pattern = Pattern.compile("[\n]+");
String[] results = pattern.split(input);
Map target = new HashMap();
//这里设置一个开始字符,也可以修改成察看文件获取
String current = "A";
ArrayList currentList = new ArrayList();
for(String item : results)
{
String[] currentLine = Pattern.compile("[,| ]+").split(item);
if(!current.equals(currentLine[0]))
{
target.put(current, currentList);
current = currentLine[0];
currentList = new ArrayList();
}
currentList.add(currentLine[1]);
}
target.put(current, currentList);
System.out.println(target);
}

2006-08-30

将一个branch更新到head

之前把从cvs上checkout出来的代码改了又改,面目全非的,怕出什么问题,就把它当作一个branch提交了。现在想把branch扶正为head。
先将这个branch”replace with”head,然后这个工程就变成head了,然后让它跟cvs上的branch比较(”compare with another branch or version”),然后”override and update” ―― 米有”commit and update”因为不是一样的存储分支。最后得到的就是head的分支却是branch的内容,接下来?commit呗~

2006-08-29

getAdapter

public Object getAdapter(Class key) {
if (IPropertySource.class == key) {
if (getModel() instanceof IPropertySource)
return getModel();
if (getModel() instanceof IAdaptable)
return ((IAdaptable)getModel()).getAdapter(key);
}
if (AccessibleEditPart.class == key)
return getAccessibleEditPart();
return null;
}

这就是为什么model只要继承IPropertySource并写好PropertyDescriptor就可以在属性页显示出model的属性。

2006-08-23

多线程环境下访问同步方法

public class ThreadTest
{
static ThreadTest tt = new ThreadTest();
class Thread1 extends Thread
{
public void run()
{
while(true)
tt.read();
}
}

class Thread2 extends Thread
{
public void run()
{
while(true)
tt.write();
}
}

private int count;

public synchronized void read()
{
System.out.println("read " + count);
try
{
Thread.sleep(3000L);
} catch (InterruptedException e)
{
e.printStackTrace();
}
System.out.println("read " + count);
}

public synchronized void write()
{
System.out.println("write " + count++);
}

public static void main(String[] args)
{
ThreadTest test = new ThreadTest();
test.new Thread1().start();
test.new Thread2().start();
}
}
“锁”是指对象锁,没有“成员锁”或“函数锁”。访问一般函数(unsynchronized)时不用获取对象锁。访问同步函数时须获取函数所在对象的对象锁,这时其它同步函数、方法皆不可访问,而非同步的成员可以。

让2个div在同一行显示

在css style里这么写就OK了:
div
{
display:inline
}
可能会出现中英文对齐问题,加一个vertical-align:text-bottom就好了

思考

一、传输给controller(EditPart)的model应该是谁?
这里的model目前有2个类别:IDOMNode和ElementBase。IDOMNode是纯DOM结构的一种实现,来自wtp,主要添加了INodeAdapter的接口方便扩展(请理解一下adapter的概念)。提供了所有关于DOM的操作,比如createElement, getChild, removeChild。而ElementBase则是IDOMNode的一个扩展(即继承了INodeAdapter),它拥有一个IDOMNode的成员,以及作为model的PropertySource描述实现(对应model属性的切实描述的定义)和属性变更事件支持(PropertyChangeSupport)。问题是我传给controller的model应该是IDOMNode还是ElementBase呢?我倾向于IDOMNode,它可以更清晰地表明ElementBase只是用来描述属性(这种情况下,属性等数据全存储在IDOMNode里,ElementBase只负责对属性的更改操作及描述这个属性-是list还是文本形式全由自己控制)。但是起初的设计是model面向ElementBase的(IDOMNode是后来加进来的),更改起来会有一定的麻烦。而且如何将IDOMNode的属性变更事件支持添加进来也是个待解决的问题(或许是很简单的设计哲学,不过在搞清楚具体问题领域前似乎很难,adapter能做到的事想像不到尽头的J)。
所以controller所能看到的依然是ElementBase。
二、关于model的初始化。
在上个问题结论的基础上,还有个ElementBase的成员初始化的问题。ElementBase里有个IDOMNode成员,存储node应有属性,它可以是在运行form定义程序的过程中动态产生的(类似工厂),也可以是从form定义程序加载时生成的(类似反序列化)。这两种方式怎么统一起来呢?感觉上应该跟ElementCreationFactory有关系的说~

顺带描述一下DOM Document的产生过程:
首先需要提供一个xml文件(由来请参看FormDesignEditor.getEditorInput()的注释),这个文件会先由StructuredTextEditorXML解读(来自wtp的xml editor),它会生成一个IDOMDocument对象并保存在DocumentTransferer里,然后form图形定义editor会从DocumentTransferer获取这个对象作相应的初始化:
初始化children à生成model的Element(ElementCreationFactory)à生成EditPart(controller,是由rooteditpart根据EditPartFactory生成的)à生成figure

2006-08-17

Adapter

Adapter实际上在eclipse以前的版本里是叫做extension。是用来扩展功能的。因为你实现的类可能是多功能的复合体,但是某个请求者只需要它其中的一种功能或者叫做某一方面,你怎样展示给请求者呢?你可以象下面这样写函数:
Public Object getAdapter(Object key);
这个函数会根据输入的key来返回对应的对象(功能/方面)。比如一个属性视图想从你的类中抽取属性信息,而你的类里刚好有一个PropertyDescriptor的成员,这样,在判断出对方意向后就可以把成员送出去:
If(key == PropertyDescriptor)
Return myPropertyDescriptor;
有个小要点需要注意的是,你需要在getAdapter最后添上
Super.getAdapter();
这么一来保证了实现你想要的能力而不损失父类默认拥有的能力。

2006-08-10

dom相关概念

org.w3c.dom.*
有根元素,文本,属性,标签节点四种,还有个Node 接口是整个文档对象模型的主要数据类型。它表示该文档树中的单个节点。当实现 Node 接口的所有对象公开处理子节点的方法时,不是实现 Node 接口的所有对象都有子节点。例如,Text 节点可能没有子节点,且将子节点添加到这样的节点将导致引发 DOMException。
今天写代码的时候碰到个小问题
IDOMDocument document = getDocument();
document.createElement("myelement");
debug发现这个元素根本添加不到document上去,后来改了下
document.getDocumentElement.appendChild("myelement");
就添加上去了=_=#! , 不知道是它API名字误解了我还是我理解能力有问题....

2006-08-02

添加Jar

添加jar到buildPath和plugin depedencies是不一样的,buildPath就是很简单的构造路径,而后一个就需要声明bundle,也就是plugin.xml文件,在启动/调试eclipse application的时候会将声明的插件先安装上去。如果你只把一个jar添加到 plugin depedencies里eclipse会发现它不能安装这个插件从而导致eclipse application不能启动/调试。

以前一直以为这两种形式是一样滴。。。

2006-07-31

过滤eclipse中的problem

eclipse中的problem默认是显示所有project里的所有problem,但是我只想看我所选中的包或者java文件的错误,可以这么做:在problems页创建一个新filter,在右面的select项里选“on selected element and its children”就OK了

2006-07-19

MVC中的controller

今天看gef代码头疼,就跟刘紫高探讨了下MVC的概念,其实里面的controller是比较突出的,view和model没有什么联系,全靠controller进行交流,跟controller联系比较紧的有个概念叫EventListener,这个可以引起view和model的状态的改变,而改变都是由controller来执行的,EventListener是对Event的监听,Event有这么几种:

  1. 用户参与的 比如鼠标事件,键盘事件等也可以归为IO一类罢,当时没想到
  2. 程序性的 即事件是由程序触发

Event里面有个list,列出当事件发生时需要通知的对象s,而这些对象都是EventListener的子类。在GEF中,controller负责代理更新view和model。

2006-07-13

serialVersionUID作用

serialVersionUID

serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。

2006-07-10

draw2d 中的figure概念

figure有“外形, 轮廓, 体形, 图形, 画像”的意思,在draw2d中的概念就相当于swing中的panel。可以:

  1. 注册/取消注册监听器
  2. 事件管理
  3. 定位鼠标位置
  4. 添加删除子figure
  5. 访问 layoutManager, figure坐标、大小,工具集
  6. 焦点设置与获取
  7. 透明度与可见性
  8. 绘画
  9. validate

2006-07-02

redeploy is out of date due to change in the ....

用myeclipse布署到tomcat老报这个错,改了老半天,后来发现我的资源管理器正打开着我的那个web app的目录,然后把它关掉,就可以成功布署了,真是晕,以前也碰到过,糊涂乱搞就过去了,原来是因为有程序占着文件导致myeclipse不能重新布署的时候替换造成的。

2006-06-27

form提交

用httpclient提交数据时碰到个问题:

这个好像不是值对的关系了,有个checked,三个值怎么处理呢?
后来查了下html spec,按它的说法,不是所有的form数据都会被提交上去,只有"successfull controls"才可以,也就是说,当checkbox为checked时,它的name/value才会被提交,否则在提交时将会忽略这项。

还有一点没解决就是好几个checkbox有相同名字时,并且全是"successful controls",那提交时怎么区分name/value呢?liuzg说需要通过js处理然后动态地修改name值使其不一样后再提交。8过httpcliet能执行js嘛? 留着问题。。。

2006-06-14

类布署不到服务器上的问题

用myeclipse开发的时候,写了一个action类,却总也布署不上去,执行的时候老说找不到这个action的instance,后来偶然发现我写的类并没有编译成class文件从而布署,然后察看了一下buildpath,原来有一个jar系统找不到,所以在正确配置这个包前它不会编译任何添加进来的文件。

2006-06-01

http上传文件

通用上载组件的原理及实现

原来文件的上传不是单独线程执行的,而是和一般的form元素一样进行统一编码后以流的形式传给server。至于从服务器端的解析,因为上传的form是结构性数据,所以...

2006-05-27

DWR是个好东西

DWR

如果你有个POJO写成下面的格式:

public class DwrMagic
{
public String reply()
{
return "oh, dwr magic !";
}
}

你需要通过javascript访问到这个方法并展示在页面中,容易么?DWR告诉你,相当容易:
DwrMagic.reply(function(replycontent){alert(replycontent);}

Woo~ Cool~

下面讲一下具体实施办法:
下载一个dwr.jar放到WEB-INF/lib目录下,然后修改web.xml,添加个servlet:
不贴代码了,用blogger的编辑器编辑的时候有些麻烦,它自动处理代码,即使你不愿意它处理,看dwr上的getstart吧
然后再创建个dwr.xml放在web.xml同目录下,并把自己创建的类的信息写进来:
不贴代码了,用blogger的编辑器编辑的时候有些麻烦,它自动处理代码,即使你不愿意它处理,看dwr上的getstart吧
然后建立个testdwr.html文件:
把这几个script文件连接进来:
/dwr/dwr/interface/Demo.js
/dwr/dwr/engine.js
然后再写个javascript脚本函数:

function getData(str)
{
alert(str);
}
function getReply()
{
Demo.reply(getData);
}

然后随便找个地方调用getReply()就可以看到效果了,非常cool~

2006-05-25

代用户与server交互

Cookie怎么保存

JDK里没有参考实现,只有一个CookieHandler,而且是全局的,也就是说在一个JVM内你只能代表一个用户,后来找到个JCookie,不过操作起来挺麻烦的,后来感觉好像还和IE有关联,因为我没开IE的时候它就运行出错,开着就一切OK =_=#!

最后找到一个很好的:HttpClient,是apache的,早找到就好了,T_T,挺好用的,而且还带了些sample,常用的功能基本都能展示出来,暂时先不贴代码....

2006-05-24

建立ssl连接并通过BASIC认证

贴段代码了,没啥好说的哦

public void testHttpsConnection() throws Exception
{
URL url = new URL("https://www.blogger.com/atom");
X509TrustManager xtm = new X509TrustManager()
{
public void checkClientTrusted(X509Certificate chain[], String authType)throws CertificateException{}
public void checkServerTrusted(X509Certificate chain[], String authType)throws CertificateException{}
public X509Certificate[] getAcceptedIssuers()
{
X509Certificate[] cert = {};
return cert;
}
};
TrustManager mytm[] = {xtm};
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(null,mytm, null );
SSLSocketFactory sf = ctx.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sf);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
String usernamePassword = "username" + ":" + "password";
String encoding = new BASE64Encoder().encode(usernamePassword.getBytes());
conn.setRequestProperty("Authorization", "BASIC " + encoding);
InputStream in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
IoUtil.transfer(in, out);
System.out.println(new String(out.toByteArray()));
}

把用户名和密码改掉了,嘿。只要你注册一个blogger的账号就可以顺利获得结果 :)

还有,blogger的atom API在

2006-05-23

从群里偷偷瞄来的,收藏下~

Re: SSLHandshakeException: could not find trusted certificate
Sep 2, 2002 6:40 AM (reply 1 of 12)



if you work in windows in control panel you have java plugin -
there is column certificates then you click on secure site and import public key.

in unix execute ControlPanel from your java direcotry and makes the same.
it could help.

l33t0n3
Posts:5
Registered: 9/3/02 Re: SSLHandshakeException: could not find trusted certificate
Sep 3, 2002 9:31 AM (reply 2 of 12)



There are two ways to fix your problem. The first is add the certificate(s) of the target site to your TrustStore.

In the JSSE, the TrustStore object is a Keystore file which contains the public key(s) and any Root keys for a server certificate. You can add the key to your truststore by using keytool. (read JSSE documentation http://java.sun.com/products/jsse/doc/guide/API_users_guide.html to learn more about keytool):

In order to do this you will need to get the servers public (not private) key and any root certificates and then use the keytool.

Unfortunately, most of the time this is way too much of a pain in the butt to do for every ssl connection. For this reason, you can actually create your own TrustManager implementaiton and assign it to the SSLSocketFactory. The SSLSocketFactory can either be used by you directly, or you can let the java.net.URL connection factory handle the fetching and reading of sockets for you. I highly recommend using java.net.URL because it will load the https handler and you won't have to worry about writing the http requests properly.

First, you must create an implementation of the TrustManager factory. I recommend that for your first go you just trust everything (i.e. the isServerTrusted(X509Certificate[] Servers) method should always return true).

Make sure you have specified your provider (system property or dynamically as shown (this is jdk1.3 w/ JSSE 1.0.3, with jdk 1.4 it s bit different)...

java.security.Security.addProvider(
new com.sun.net.ssl.internal.ssl.Provider());

get your ssl context...
ctx = SSLContext.getInstance("TLS");

create an array of 1 object containing your TrustManager...
TrustManager[] _trustm = {new your.BogusX509TrustManager()};

And then tell the context to init using your trust manager...
ctx.init(null, _trustm, null);

make that your default socket factory for ssl connections...
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

Now your SocketFactory (and TrustManager) will be used for any new https connection you open in this instance. Since you set isServerTrusted to always return true, you will trust all certificates. You can also go a bit farther and validate certificates and store certificates in your TrustStore...

2006-05-22

dom4j解析的时候乱码

link: "java中文乱码解决方案和经验"

用DOM4J读节点数据的时候老出现中文乱码,我开始以为是DOM4J的问题,然后就查,最后看到一个解决方案,感觉不太爽,然后就接着找,后来不知道怎么就发现原来错误不在DOM4J。

主要是我读文件后把它存成byte[]格式的了,然后直接
byte[] gdpBytes = retrieveBytes();
String text = new String(gdpBytes);
Document doc = DocumentHelper.parseText(text);


这样是不对滴,就在第二行出的问题,这个时候还需要作一下编码声明处理:
String text = new String(gdpBytes,"utf-8");

这样就OK了。还有几个连接,虽然没用到,但是以后可能有用:
1 2

2006-05-19

hibernate中的binary

在mapping文件中声明了一项用来存储文件的属性“bytes”:





实际上是把bytes映射成数据库表中的varchar,然后看了一下mysql的文档,varchar和binary是一样的属性,但是为什么是varchar而不直接binary就不明白了。但是varchar显然不够用于存储文件,执行存储的时候报错说
Data truncation: Data too long for column 'bytes' at row 1
后来就把它改成varbinary,顺便把最大值设为55535,然后就通过了。

没错,不是65535,如果那样的话会报错说需要把字段类型转换为BLOB。

用的是hibernate2.1, mysqlconnector5, mysql5.0

2006-05-18

瞎忙活了

鼓捣了半天,虽然没明白怎么回事,但是还是出了结果了。

就是想通过hbm.xml产生.sql文件,目的就是产生数据库表。然后就使劲地看build.xml文件,愣没看出来啥错,但是编译就是不通过,后来把build.properties改了一下,还是有错,然后把我添加到buildpath的一些包啊什么的去掉,然后就一切OK了。

见鬼

2006-05-16

Unbound classpath variable

在线教程: "Unbound classpath variable"

是变量没定义或定义的不对,可以在java Build Path里更改或增加variable。

swimlane

swimlane: "A swimlane therefore has one assignment and all tasks that reference a swimlane should not specify an assignment."

如果在一个任务中声明了swimlane,就表示你也把需要做的任务也移交给它了,所以不能再在task声明里另声明assignment.

现在才明白,wfe是把所有的操作(人工&自动)都分门别类交给swimlane来处理,这样,只要把swimlane声明好了,操作也就固定了,剩下的问题就是这些swimlane的执行顺序是什么样的?

当然,还有一个decision,需要写script或代理等,这里应该可以和规则引擎联系起来吧。

Integer.parseInt()

在org.jbpm.webapp.tag.ProcessImageTag看到这个代码:
result[0] = Integer.valueOf(node.attribute("x").getValue()).intValue();
看着不怎么舒服,其实有个更简洁的途径:
result[0] = Integer.parseInt(node.attribute("x").getValue());
这个是好久以前就知道的,现在看到代码就突然想起来了,先记一下,嘿

2006-05-11

jbpm里的Authorization

Chapter 17. Security:"Authorization is optional, and there is no authorization implementation yet. "
找了半天,原来授权部分还没实现,只有个identity包,是实现认证部分的,记得在jbpm.cfg.xml里有个服务好像叫"authentication",得去看看那个starter-kit里是如何进行授权的了,应该是很简陋的那种吧,比如执行某个task的时候,预先查下数据库,看有没定义这个用户的可以执行,行就通过(本来就应该是这么回事儿嘛,有什么简陋的丫):

Token 的概念

Token
Token这个概念,现在有点糊涂了,按胡工说的,就是标识流程所处的状态,而我理解的是流程当前流到节点的标识,嗯,差不多的概念。。。
哦,找到了,在javadoc里:
represents one path of execution and maintains a pointer to a node in the ProcessDefinition. Most common way to get a hold of the token objects is with ProcessInstance.getRootToken() or ProcessInstance.findToken(String).
意思就是说一个token代表一条执行路径而且维护一个指针用来标识一个节点(就是我所理解的那层意思,不过我没理解到“代表一条执行路径”).这么说的话token的在流程定义的时候就已经确定了,按照图论......

2006-05-10

知道怎么访问hsqldb的数据文件了

首先下载hsqldb.然后把要查看的数据文件(总共五个)copy到hsqldb_home/demo目录下,然后运行runManager.bat,然后在出现的选择框里选stand alone模式,在url里象这么写:
jdbc:hsqldb:file:d:/java/hsqldb/demo/localDB
其中的"d:/java/hsqldb/demo/localDB"就是文件的全路径.最后把用户名密码输入就OK了.

stand alone 模式的意思是hsqldb运行在应用程序所再JVM内,这样可以使性能得到最优化,因为数据传输不再需要通过网络.但是这也限制了它不能通过外部程序访问.

2006-05-09

将JBPM数据库改为MySQL

其实挺简单的,不知道开始的时候不行,后来看自己代码太乱整理了一下然后就好了,奇怪了 @_@ :

环境就是jbpm的GPD, 新建立个工程后会自动产生一些结构性的文件和目录,把src/config.files下的hibernate.cfg.xml作下修改,大致就类似这个:
hibernate.dialect=org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class=com.mysql.jdbc.Driver
hibernate.connection.url=jdbc:mysql://localhost:3306/jbpm
hibernate.connection.username=root
hibernate.connection.password=rootpassword
然后就是设置数据库了,得先找到ddl的脚本,我查了半天,最后终于在jbpm-starter-kit-3.1里找到了,是在/jbpm-db/build/mysql/目录下面的,有个mysql.create.sql,执行它,打开MySQL看就会看到一大堆的表,嗯,这部分工作就算完成了.
然后就是写TestCase,在这之前随便用Designer作个工作流图.

public class JayTestProcess extends TestCase
{
public void testSimplePersistence()
{
JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext();
ProcessDefinition definition = ProcessDefinition.parseXmlResource("qqq.par/processdefinition.xml");

//do deploy process definition to database :
try
{
jbpmContext.deployProcessDefinition(definition);
}finally
{
jbpmContext.close();
}
}
}

回去再看一下MySQL里面就有数据了,大概就是这么回事吧.还有个问题没解决就是在执行过程中会有WARN 说
22:16:21,638 [main] WARN EhCacheProvider : Could not find configuration [org.jbpm.graph.def.Node]; using defaults.
等等一大堆的找不到configuration,不知道它是不是在找用户自定义的configuration?

.sql脚本文件的执行

shell> mysql -h host -u user -p <>

Enter password: ********

哦,挺简单的嘛,以前怎么就不想去查捏

Task的访问权限

user就是单一用户,而actor是指角色。
Task的执行通过assignment来实现:
public interface AssignmentHandler extends Serializable
{
void assign( Assignable assignable, ExecutionContext executionContext );
}

其中的Assignable就是拥有此任务执行权限的人或角色的列表:
public interface Assignable
{
public void setActorId(String actorId);
public void setPooledActors(String[] pooledActors);
}
你可以通过二个函数来声明这个task是只某个人能执行还是一些角色都可以执行。

2006-04-30

ActionHandler与异常

JBPM中的ActionHandler未实现对异常的处理,也就是说,如果你的ActionHandler出现异常,那么它无奈地只能交给它的上级(Process)处理,这可能导致Process不能继续执行,而这并不是我们期望的,因为一些不重要的异常我们可以忽略。

runa WFE引入了一个概念叫"bot",是"robot"的变体,可以将ActionHandler所需要处理的内容全部移交给bot来处理,这个过程是基于消息的,即使bot出了问题也不会影响到ActionHandler。

2006-04-29

关于IFile

Eclipse中的IFile只是个概念性的东西,它并不与文件系统中的某个文件挂钩,而且IFile只能在workspace里进行定位。
IPath destPath = new Path("/test/processdefinition.xml");
IFile destFile = ResourcesPlugin.getWorkspace().getRoot().getFile(destPath);
如果想把东西输出到IFile所指定的文件上,进行create动作就OK了:
InputStream stream = getClass().getClassLoader().getResourceAsStream(definitionFile);
destFile.create(stream, true, getMonitor());

这个stream和getMonitor()应该注意一下.以前一直不明白jar文件中的东西是怎么通过路径获得的,呵呵。
还有这个getMonitor():
private IProgressMonitor getMonitor()
{
return configurer.getStatusLineManager().getProgressMonitor();
}
不是在哪里都可以获得IProgressMonitor的,目前我知道的就是和commands注册的地方有关联的,比如Action,可以通过它的IActionBarConfigurer来查找到。

2006-04-28

压缩包内的资源数据是通过ClassLoader获得的

以前就一直有这个疑问,今天一不小心看到了:
String resourceName = "org/jbpm/ui/resource/gpd.xml";
InputStream stream = getClass().getClassLoader().getResourceAsStream(resourceName);

2006-04-27

StackOverflow了

在DesignerApplicationWorkbenchWindowAdvisor的构造函数里写了一句就出现了这种情况:
configurer.getWindow().getWorkbench().openWorkbenchWindow(file);
想了一下,原因挺简单的。

嗯...又有了点了解,不过总找不到本像样的书看,老这么试可真不是办法

获得一个文件真是麻烦

IPath path = new Path("org.jbpm.ui/gpd.xml");
IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
IFile file = workspaceRoot.getFile(path);

文件只能通过workspace范围内,那个org.jbpm.ui是project名,看着挺别扭的...

2006-04-26

补个日记吧

上次田野跟我说的事务执行细节:
有个大前提:所有操作都只是函数调用

函数放在线程栈内(注意是一个线程噢),从上往下依次执行,如果某个地方抛出异常,则整个栈的执行被回退。

嗯,大概就是这么说的,以前我也见到过,现在虽然明白但是还是不清楚。有个问题就是:每个函数都应该支持do和undo吧?要不怎么回退呢

对plug-in进行二次开发

其实方法挺简单的,只是刚开始的时候不知道。在package Explorer里右键选择import...,然后在出来的wizard里选择"external plug-ins and fragments",里面会有好多plug-ins可供选择,都是你的Eclipse目前能识别的所有的。选择一个finish就OK了,Eclipse会独立创建一个新project把所需要的东西复制过来。这样就跟一个普通plug-in project一样了,呵呵。

如果想以Eclipse Application方式运行,还需要写点东西的说,不晓得怎么把模板导进来,那就不用写了嘿嘿。

贴代码不说话

Thread.currentThread().getContextClassLoader().getResource();

dont code like above, but :
Thread current = Thread.currentThread();
ClassLoader oldLoader = current.getContextClassloader();
try{
current.setContextClassloader(getClass().getClassloader());
//call library code here
}finally{
current.setContextClassloader(oldLoader);
}

Eclipse Product的创建方法

昨天找了半天都没找到:
新建一个plug-in Project,然后在wizard里面有个选项,叫"would you like to create a eclipse product application?"选择yes就OK了。

2006-04-20

把文档写出来了

也没用多少时间,只是把网上的东西copy下来,然后修改一下适合版面罢了。当然,写出来的肯定是自己懂的,要不别人问起来那不丑大了,呵呵。

今天印象最深的是澄清了一个概念:execution,这个和petriNet里的Token是一样的意思,而我之前以为token应该是和transition挂钩的。=_=#!
execution是可以传递的,通过Node或Transition,其实Transition惟一的作用就是传递Execution到Node。Action可以产生新的Execution。这和petriNet中place可以fork出新token是一样的。

jBPM实现太多东西了,一时间还看不全面,比如asynchronous, concurrent, persistence,jms,transaction。后来因为找不到web-based 流程设计ui,跑去jboss的forum问了一下,本是不期望答案的,结果没过三分钟就有人来回答,虽然答案不尽人意,却也挺高兴的,我很久没在论坛上说过话了,也很少看,更何况是e文的,因为以前问的问题很少有人回答,就再不去论坛了,在CSDN上的号很久都没去过了。现在看来,真是个错误的决策!

以后要多多逛论坛啦 ^_^

2006-04-19

满累的这几天

其实就一件事:学习工作流引擎。看的全是英文资料了,进度不是很快。而且白天的工作效率不太高。眼睛有点不舒服,估计是看显示器太长时间了。

有点急了

本来前天给我分配的任务是找个workflow引擎研究一下,后来PM昨天跟我说不要看太深,只要有好的用户体验就一切OK,后台倒不是很重要,但是当时我已经看了些JBPM的东西,不想就这样放弃了,然后就继续往下看,顺便也加个心眼儿,看看有没附加的UI的边缘产品,今天为止只找到一个,就是JBOSS里带的Eclipse插件,看了下源代码,设计的倒是满清晰,就是分离的不如我期待的那么开。

我就在想了:如果加一个web-based process generator,工作量会不会满大?

思考了半天,觉得主要有这几个问题:

  • jBPM相关概念,不知道谁熟悉?
  • JS及AJAX等用来产生UI的技术,这部分需要完全自己实现,没有可借鉴的。
  • DOM操作以产生processDefinition文件,没接触过。
  • 动态加载processDefinition能否实现。


后天就要交份报告出来,虽然没具体说要包含什么内容,但我觉得这几条总还是应该有的:

  • 工作流概念、背景、作用
  • jBPM的特点
  • 如何使用jBPM,最少要有个DEMO,比如TestCase什么的
  • 怎么把它集成到OA中来

2006-04-18

jBPM中涉及到的petriNet

petri网 用于描述异步、并发的系统模型,是所有流程定义语言的始祖。

主要有这么几个概念:
Node
Transition变迁
Token
类似状态机,有初始和终节点,Node可以通过Transition达到状态变化。Token用来追踪流动情况。具体还是看wiki吧。

2006-04-17

在js中使用jsp脚本

本来是想表达这个意思:
var username = <%=(String)session.getAttribute("btoa_userName")%>
结果不成,执行不了,问了下同事,很简单,把jsp脚本引用起来就OK了:
var username = '<%=(String)session.getAttribute("btoa_userName")%>'

2006-04-14

一个有趣的东西

SWIXML - Generate javax.swing at runtime based on XML descriptors

这个可以通过xml描述文件来产生swing应用程序,就跟html一样,挺有意思,记得ms也吹过什么下一代编程,就是这个模式,呵呵

这个article是一个helloworld

2006-04-10

Behavioral Extensions to CSS

Behavioral Extensions to CSS

今天想在CSS文件里定义tag的事件,找了半天,终于找到这个,原来叫HTML component(HTC),这里所描述的比我想的更进一步,还可以自定义tag的属性并作相应扩展。
在CSS里面,只要引用一个HTC文件就可以了:
behavior:url("/sample.htc");
我关注的是:firefox支持这个吗?查了一下没查到,不知道我查的方法对不:
firefox support html component ?
这样在google里没出什么结果。我觉得应该支持吧,是很自然的一个css extension

JSON versus XML

Mashup Data Formats: JSON versus XML @ JAVA DEVELOPER'S JOURNAL

XML有安全限制,就是说,XMLHttpRequest只能请求同本网页在同一domain下的XMLresponse,但json好象就没这个限制。两种方法各有千秋,作者主张把json嵌入到xml里,提出了一种新的观点:XJAX,即x-platform javascrip and xml,也就是说,不提供基础服务,而是在其上建设更个性化的服务,感觉这很像豆瓣网。web2.0。
而且作者也建设了一个网站:batBack,能为你的blog提供一些cool的服务

2006-04-03

把blogspot用做开发blog

blogspot不太适合做开发用blog,因为我要贴些html代码都不行,它会自动进行解释,它的那个多格式文本也不太厉害。

中文网页显示乱码的问题

怎样制造乱码?
用EditPlus新建一个html文件,随便打几个中文进去。必须保存且存为utf-8格式,然后预览就会发现是乱码。

解决办法
在原来的文件里添加一个数据元:


OK了,根据我的判断,浏览器在加载html文件的时候是按默认方式(ANSI编码方式)处理,而utf-8方式下的中文编码和ANSI下的不是相同的,所以会产生乱码。浏览器应该会首先读取数据元,当它发现网页声明它的编码方式时就会动态的转换处理方式(在这里是以utf-8方式继续读文件)

这里有个前提是,数据元的声明必须是以英文形式存在的,因为utf-8下和ANSI下英文编码是一致的,也就是说,不论以哪种方式读英文都会获得准确信息

PS: 我觉得“英文”改成“ascii”好些,但是不知道准确不?呵呵

中文网页显示乱码的问题

怎样制造乱码?
用EditPlus新建一个html文件,随便打几个中文进去。必须保存且存为utf-8格式,然后预览就会发现是乱码。

解决办法
在原来的文件里添加一个数据元:


OK了,根据我的判断,浏览器在加载html文件的时候是按默认方式(ANSI编码方式)处理,而utf-8方式下的中文编码和ANSI下的不是相同的,所以会产生乱码。浏览器应该会首先读取数据元,当它发现网页声明它的编码方式时就会动态的转换处理方式(在这里是以utf-8方式继续读文件)

这里有个前提是,数据元的声明必须是以英文形式存在的,因为utf-8下和ANSI下英文编码是一致的,也就是说,不论以哪种方式读英文都会获得准确信息

PS: 我觉得“英文”改成“ascii”好些,但是不知道准确不?呵呵

中文网页显示乱码的问题

怎样制造乱码?
用EditPlus新建一个html文件,随便打几个中文进去。必须保存且存为utf-8格式,然后预览就会发现是乱码。

解决办法
在原来的文件里添加一个数据元:


OK了,根据我的判断,浏览器在加载html文件的时候是按默认方式(ANSI编码方式)处理,而utf-8方式下的中文编码和ANSI下的不是相同的,所以会产生乱码。浏览器应该会首先读取数据元,当它发现网页声明它的编码方式时就会动态的转换处理方式(在这里是以utf-8方式继续读文件)

这里有个前提是,数据元的声明必须是以英文形式存在的,因为utf-8下和ANSI下英文编码是一致的,也就是说,不论以哪种方式读英文都会获得准确信息

PS: 我觉得“英文”改成“ascii”好些,但是不知道准确不?呵呵

中文网页显示乱码的问题

怎样制造乱码?
用EditPlus新建一个html文件,随便打几个中文进去。必须保存且存为utf-8格式,然后预览就会发现是乱码。

解决办法
在原来的文件里添加一个数据元:


OK了,根据我的判断,浏览器在加载html文件的时候是按默认方式(ANSI编码方式)处理,而utf-8方式下的中文编码和ANSI下的不是相同的,所以会产生乱码。浏览器应该会首先读取数据元,当它发现网页声明它的编码方式时就会动态的转换处理方式(在这里是以utf-8方式继续读文件)

这里有个前提是,数据元的声明必须是以英文形式存在的,因为utf-8下和ANSI下英文编码是一致的,也就是说,不论以哪种方式读英文都会获得准确信息

PS: 我觉得“英文”改成“ascii”好些,但是不知道准确不?呵呵

Class-Based vs. Prototype-Based Languages

Core JavaScript 1.5 Guide:Class-Based vs. Prototype-Based Languages - MDC

感觉javascript的特性很神奇,原来还有个名词表述这些 : prototype-based。 这是不是所谓的动态语言的特性呢?

2006-03-27

javascript中对象产生方法

在javascript中对象与函数并无很大区别:
1.标准方法
obj = new Object()
obj.name = "objname"
...
2.函数方法
function Editor()
{
this.doA = outerDoA
this.doB = outerDoB
}

function outerDoA()
{
document.write("hellow")
}

function outerDoB()
{
document.write("hellow")
}


obj = new Editor

obj.doA() //get it!

最后一行不能写成 obj.doA,否则不会显示

2006-03-24

Continuous Integration

Continuous Integration

记一个词:Continuous Integration. martin fowler发明的。描述了XP开发的一个原则,大体表示要coding, testing, integrating同时进行,而不是传统的顺序结构

2006-01-07

把java的和生活的分开吧

才晓得blogger可以创建多个blog的好处了

不过话说回来,我这折腾来折腾去的,所写的日志也都乱了套的 T_T

安心点写吧