星期日, 十二月 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的运行环境,我的Eclipse是3.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,修改Name为EventDemo,并在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
