星期日, 十二月 14, 2008

[Objective-C]分数类

// FILE FractionNumber.h

#import



@interface FractionNumber : NSObject {

int numerator;

int denominator;

}


@property(readwrite) int numerator, denominator;


-(id)initWithIntegers:(int)x numbery:(int)y;


- (NSString *)stringValue;

- (float)floatValue;

- (double)doubleValue;


- (void)add:(FractionNumber *)fn;

- (void)sub:(FractionNumber *)fn;

- (void)div:(FractionNumber *)fn;

- (void)mul:(FractionNumber *)fn;


+(int)gcd:(int)x numbery:(int)y;

+(int)lcm:(int)x numbery:(int)y;


+ (FractionNumber *)parseFractionNumberWithString:(NSString *)stringNumber;

+ (FractionNumber *)parseFractionNumberWithFloat:(double)floatNumber;

+ (FractionNumber *)parseFractionNumberWithInteger:(int)intNumber;


@end



// FILE FractionNumber.m

#import "FractionNumber.h"



@implementation FractionNumber


@synthesize numerator, denominator;


-(id)init

{

[super init];

numerator = 0;

denominator = 1;

return self;

}


-(id)initWithIntegers:(int)x numbery:(int)y

{

[super init];

numerator = x;

denominator = y;

return self;

}


- (NSString *)stringValue

{

return [[NSString alloc] initWithFormat:@"%.11g", [self doubleValue]];

}


- (float)floatValue

{

return (float)numerator/(float)denominator;

}


- (double)doubleValue

{

return (double)numerator/(double)denominator;

}


- (id)copy

{

FractionNumber *fn = [[FractionNumber alloc] initWithIntegers:numerator numbery:denominator];


return fn;

}



- (void)add:(FractionNumber *)fn

{

int x1 = numerator;

int y1 = denominator;

int x2 = [fn numerator];

int y2 = [fn denominator];

int lcmnum = [FractionNumber lcm:y1 numbery:y2];

x1 = lcmnum / y1 * x1;

x2 = lcmnum / y2 * x2;

numerator = x1 + x2;

denominator = lcmnum;

int gcdnum = [FractionNumber gcd:numerator numbery:denominator];

while (gcdnum > 1)

{

numerator /= gcdnum;

denominator /= gcdnum;

gcdnum = [FractionNumber gcd:numerator numbery:denominator];

}

}

- (void)sub:(FractionNumber *)fn

{

int x1 = numerator;

int y1 = denominator;

int x2 = [fn numerator];

int y2 = [fn denominator];

int lcmnum = [FractionNumber lcm:y1 numbery:y2];

x1 = lcmnum / y1 * x1;

x2 = lcmnum / y2 * x2;

numerator = x1 - x2;

denominator = lcmnum;

int gcdnum = [FractionNumber gcd:numerator numbery:denominator];

while (gcdnum > 1)

{

numerator /= gcdnum;

denominator /= gcdnum;

gcdnum = [FractionNumber gcd:numerator numbery:denominator];

}

}

- (void)div:(FractionNumber *)fn

{

FractionNumber *newFn = [[FractionNumber alloc] initWithIntegers:[fn denominator] numbery:[fn numerator]];

[self mul:newFn];

[newFn release];

}

- (void)mul:(FractionNumber *)fn

{

int x1 = numerator;

int y1 = denominator;

int x2 = [fn numerator];

int y2 = [fn denominator];

int gcdnum = [FractionNumber gcd:x1 numbery:y2];

while(gcdnum > 1)

{

x1 /= gcdnum;

y2 /= gcdnum;

gcdnum = [FractionNumber gcd:x1 numbery:y2];

}

gcdnum = [FractionNumber gcd:x2 numbery:y1];

while(gcdnum > 1)

{

x2 /= gcdnum;

y1 /= gcdnum;

gcdnum = [FractionNumber gcd:x2 numbery:y1];

}

numerator = x1 * x2;

denominator = y1 * y2;

}



+(int)gcd:(int)x numbery:(int)y

{

return (!y)?x:[self gcd:y numbery:x%y];

}

+(int)lcm:(int)x numbery:(int)y

{

int y1 = x;

int y2 = y;

int gcdnum = [FractionNumber gcd:y1 numbery:y2];

while(gcdnum > 1)

{

y1 /= gcdnum;

y2 /= gcdnum;

gcdnum = [FractionNumber gcd:y1 numbery:y2];

}

return x * y1;

}


+(FractionNumber *)parseFractionNumberWithString:(NSString *)stringNumber

{

if (!stringNumber || [stringNumber length] == 0)

return NULL;

NSRange range = [stringNumber rangeOfString:@"."];

if (range.location == NSNotFound)

{

int number = [stringNumber intValue];

return [FractionNumber parseFractionNumberWithInteger:number];

}

else

{

@try {

[stringNumber doubleValue];

}

@catch (NSException * e) {

@throw e;

}

int floatNumberLength = [stringNumber length] - range.location - 1;

int ten = pow(10, floatNumberLength);

NSArray *numberparts = [stringNumber componentsSeparatedByString:@"."];

int x = [(NSString *)[numberparts objectAtIndex:1] intValue];

//x = (x * (ten - 1) + x);

//int y = ((ten - 1) * ten);

int y = ten;

int gcdnum = [FractionNumber gcd:x numbery:y];

while (gcdnum > 1)

{

x /= gcdnum;

y /= gcdnum;

gcdnum = [FractionNumber gcd:x numbery:y];

}

int num = [(NSString *)[numberparts objectAtIndex:0] intValue];

x += num * y;


FractionNumber *fn = [[FractionNumber alloc] initWithIntegers:x numbery:y];

return fn;

}

}


+(FractionNumber *)parseFractionNumberWithFloat:(double)floatNumber

{

NSString *numberString = [[NSString alloc] initWithFormat:@"%.11g", floatNumber];

FractionNumber *fn = [FractionNumber parseFractionNumberWithString:numberString];

[numberString release];

return fn;

}


+(FractionNumber *)parseFractionNumberWithInteger:(int)intNumber

{

FractionNumber *fn = [[FractionNumber alloc] initWithIntegers:intNumber numbery:1];


return fn;

}


@end


星期四, 七月 24, 2008

[JAVA]OSGi开发之Event:事件处理

首先配置OSGi Framework的运行环境,我的Eclipse3.3的,运行环境需要以下的Bundle 

  • org.eclipse.osgi 
  • org.eclipse.equinox.ds 
  • org.eclipse.equinox.registry 
  • org.eclipse.equinox.common 
  • org.eclipse.equinox.log 
  • org.eclipse.osgi.services 
  • org.eclipse.equinox.event 
  • org.eclipse.osgi.util 



操作步骤:点击菜单Run->Open Run Dialog…,在左侧的列表中,找到OSGi Framework,右键单击,New,修改NameEventDemo,并在Bundles选项卡中,选中以上列举的Bundle,然后点击Apply,点Run 


Console中输入ss来查看我们的环境是否成功运行: 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

osgi> ss

 

Framework is launched.

 

id State       Bundle

0 ACTIVE      org.eclipse.osgi_3.3.1.R33x_v20070828

1 ACTIVE      org.eclipse.equinox.common_3.3.0.v20070426

2 ACTIVE      org.eclipse.equinox.log_1.0.100.v20070226

3 ACTIVE      org.eclipse.equinox.ds_1.0.0.qualifier

4 ACTIVE      org.eclipse.equinox.registry_3.3.1.R33x_v20070802

5 ACTIVE      org.eclipse.osgi.services_3.1.200.v20070605

6 ACTIVE      org.eclipse.equinox.event_1.0.100.v20070516

7 ACTIVE      org.eclipse.osgi.util_3.1.200.v20070605

 

osgi>



OK,这样我们的Spring-OSGi的环境就启动好了,现在先关闭它。我们来建立一个Plug-in Project,命名为:EventPublisher 


首先新建一个类:com.demo.eventpublisher.Log,代码如下: 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

package com.demo.eventpublisher;

 

import org.osgi.framework.BundleContext;

import org.osgi.service.log.LogService;

import org.osgi.util.tracker.ServiceTracker;

 

/**

 * Utility class with static methods for logging to LogService, if available 

 * 

 * @version $Revision: 1.1 $

 */

public class Log {

 

static private ServiceTracker logTracker;

 

private Log() {

}

 

public static void init(BundleContext bc) {

logTracker = new ServiceTracker(bc, LogService.class.getName(), null);

logTracker.open();

}

 

static void dispose() {

if (logTracker != null) {

logTracker.close();

}

logTracker = null;

}

 

public static void log(int level, String message) {

log(level, message, null);

}

 

public static void log(int level, String message, Throwable e) {

LogService logService = (LogService) logTracker.getService();

if (logService != null) {

logService.log(level, message, e);

}

}

 

public static void info(String message)

{

info(message, null);

}

 

public static void info(String message, Throwable e)

{

log(LogService.LOG_INFO, message, e);

}

}


接下来创建一个循环发布事件的线程:com.demo.eventpublisher.TimerEvent,代码如下: 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

package com.demo.eventpublisher;

 

import java.util.Calendar;

import java.util.Hashtable;

 

import org.osgi.framework.BundleActivator;

import org.osgi.framework.BundleContext;

import org.osgi.service.event.Event;

import org.osgi.service.event.EventAdmin;

import org.osgi.util.tracker.ServiceTracker;

 

public class TimerEvent extends Thread implements BundleActivator {

    Hashtable time = new Hashtable();

    ServiceTracker tracker;

 

    public TimerEvent() {

        super("TimerEvent");

    }

 

    public void start(BundleContext context) {

        Log.init(context);

        tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);

        tracker.open();

        start();

    }

 

    public void stop(BundleContext context) {

        interrupt();

        tracker.close();

        Log.dispose();

    }

 

    public void run() {

        while (!Thread.interrupted())

            try {

                Log.info("Rasie Event");

                Calendar c = Calendar.getInstance();

                set(c, Calendar.MINUTE, "minutes");

                set(c, Calendar.HOUR, "hours");

                set(c, Calendar.DAY_OF_MONTH, "day");

                set(c, Calendar.MONTH, "month");

                set(c, Calendar.YEAR, "year");

                EventAdmin ea = (EventAdmin) tracker.getService();

                if (ea != null)

                    ea.sendEvent(new Event("com/demo/timer", time));

                Thread.sleep(60000 - c.get(Calendar.SECOND) * 1000);

            }

            catch (InterruptedException e) {

                // 忽略

            }

    }

 

    void set(Calendar c, int field, String key) {

        time.put(key, new Integer(c.get(field)));

    }

}



Plug-in ManiFest Editor中打开META-INF/MANIFEST.MF,如果安装了PDE,将会默认使用Plug-in ManiFest Editor打开。将Activator设置为com.demo.eventpublisher.TimerEvent,此时MANIFEST.MF文件中的内容如下: 

1

2

3

4

5

6

7

8

9

10

11

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: EventPublisher Plug-in

Bundle-SymbolicName: EventPublisher

Bundle-Version: 1.0.0

Bundle-Activator: com.demo.eventpublisher.TimerEvent

Import-Package: org.osgi.framework;version="1.3.0",

 org.osgi.service.event;version="1.1.0",

 org.osgi.service.log;version="1.3.0",

 org.osgi.util.tracker;version="1.3.2"

 


注意:手工写MANIFEST.MF文件时,最后一行一定要有一个回车。 


接下来我们再来建立一个Plug-in Project,命名为EventHander 


我们建立一个类,名为:com.demo.eventhandler.CustomEventHandler,代码如下 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

package com.demo.eventhandler;

 

import java.util.Dictionary;

import java.util.Hashtable;

 

import org.osgi.framework.BundleContext;

import org.osgi.service.event.Event;

import org.osgi.service.event.EventConstants;

import org.osgi.service.event.EventHandler;

 

import com.demo.internal.Log;

 

public class CustomEventHandler implements EventHandler

{

    public final static String [] topics = new String[] { 

//        "org/osgi/service/log/LogEntry/LOG_INFO", 

//        "org/osgi/service/log/LogEntry/LOG_WARNING",

//        "org/osgi/framework/ServiceEvent/REGISTERED",

//        "org/osgi/framework/ServiceEvent/MODIFIED",

//        "org/osgi/framework/ServiceEvent/UNREGISTERING",

//        "org/osgi/framework/FrameworkEvent/STARTED",

//        "org/osgi/service/log/LogEntry/LOG_ERROR",

        "com/demo/timer"}

    

    public void registry(BundleContext context)

    {

        Dictionary d = new Hashtable(); 

        d.put(EventConstants.EVENT_TOPIC, topics ); 

 

        context.registerService( EventHandler.class.getName(), this, d ); 

    }

    public void handleEvent(Event event)

    {

        if ("com/acme/timer".equals(event.getTopic()))

        {

            Log.info("Received event, EventTopic " + event.getTopic() + " " + event.getProperty("year") + "-" + event.getProperty("month") + "-" + event.getProperty("day"));

        }

        else

        {

            Log.info("Received event, EventTopic " + event.getTopic());

        }  

    }

}



我们再建立一个Activator,名为:com.demo.eventhandler.internal.Activator,代码如下 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

package com.demo.internal;

 

import org.osgi.framework.BundleActivator;

import org.osgi.framework.BundleContext;

 

import com.demo.eventhandler.CustomEventHandler;

 

 

public class Activator implements BundleActivator

{

    public void start(BundleContext context) throws Exception

    {

        Log.init(context);

        CustomEventHandler eventhandler = new CustomEventHandler();

        eventhandler.registry(context);

    }

 

    public void stop(BundleContext context) throws Exception

    {

        Log.dispose();

    }

}


OK,我们将新建立的这两个Bundle加入到运行环境中,Run 

Console中等待大约60秒后,输入log后可以在最后找到如下日志信息: 

引用原文:



>Info [1] Rasie Event initial@reference:file:../../../../../../../../Documents/workspace/EventPublisher/ 

>Info [7] Received event, EventTopic com/demo/timer initial@reference:file:../../../../../../../../Documents/workspace/ConsumerServiceDemo/ 



瞧,我们已经收到打印出来的事件接收信息了 Received event, EventTopic com/demo/timer