mirror of
https://github.com/gnustep/libs-ec.git
synced 2025-02-15 16:11:01 +00:00
1067 lines
28 KiB
Objective-C
1067 lines
28 KiB
Objective-C
|
||
/** Enterprise Control Configuration and Logging
|
||
|
||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||
|
||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||
Date: Febrary 2010
|
||
Originally developed from 1996 to 2012 by Brainstorm, and donated to
|
||
the FSF.
|
||
|
||
This file is part of the GNUstep project.
|
||
|
||
This library is free software; you can redistribute it and/or
|
||
modify it under the terms of the GNU Lesser General Public
|
||
License as published by the Free Software Foundation; either
|
||
version 3 of the License, or (at your option) any later version.
|
||
|
||
This library is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
Library General Public License for more details.
|
||
|
||
You should have received a copy of the GNU Lesser General Public
|
||
License along with this library; if not, write to the Free
|
||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
Boston, MA 02111 USA.
|
||
|
||
*/
|
||
|
||
#import <Foundation/NSArray.h>
|
||
#import <Foundation/NSCoder.h>
|
||
#import <Foundation/NSDate.h>
|
||
#import <Foundation/NSException.h>
|
||
#import <Foundation/NSHost.h>
|
||
#import <Foundation/NSObject.h>
|
||
#import <Foundation/NSString.h>
|
||
|
||
#import "EcHost.h"
|
||
#import "EcProcess.h"
|
||
#import "EcAlarm.h"
|
||
|
||
@class NSPortCoder;
|
||
|
||
NSString *
|
||
EcMakeManagedObject(NSString *host, NSString *process, NSString *component)
|
||
{
|
||
NSString *instance = @"";
|
||
NSRange r;
|
||
|
||
if (nil == host)
|
||
{
|
||
host = [[NSHost currentHost] wellKnownName];
|
||
}
|
||
// No underscores permitted.
|
||
host = [host stringByTrimmingSpaces];
|
||
host = [host stringByReplacingString: @"_" withString: @"-"];
|
||
|
||
if (nil == process)
|
||
{
|
||
process = [EcProc cmdName];
|
||
}
|
||
|
||
/* Extract the instance number from the process name (the instance would
|
||
* be a string of digits after a hyphen) if it's there.
|
||
*/
|
||
r = [process rangeOfString: @"-"
|
||
options: NSCaseInsensitiveSearch|NSBackwardsSearch];
|
||
if (r.length > 0)
|
||
{
|
||
NSString *s = [process substringFromIndex: NSMaxRange(r)];
|
||
unsigned l = [s length];
|
||
|
||
if (l > 0)
|
||
{
|
||
while (l-- > 0)
|
||
{
|
||
unichar c = [s characterAtIndex: l];
|
||
|
||
if (c < '0' || c > '9')
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
if (0 == l)
|
||
{
|
||
instance = s;
|
||
process = [process substringToIndex: r.location];
|
||
}
|
||
}
|
||
}
|
||
// No underscores permitted.
|
||
process = [process stringByTrimmingSpaces];
|
||
process = [process stringByReplacingString: @"_" withString: @"-"];
|
||
|
||
if (nil == component)
|
||
{
|
||
component = @"";
|
||
}
|
||
|
||
// No underscores permitted.
|
||
component = [component stringByTrimmingSpaces];
|
||
component = [component stringByReplacingString: @"_" withString: @"-"];
|
||
|
||
return [NSString stringWithFormat: @"%@_%@_%@_%@",
|
||
host, process, instance, component];
|
||
}
|
||
|
||
|
||
|
||
@implementation EcAlarm
|
||
|
||
+ (void) initialize
|
||
{
|
||
if (self == [EcAlarm class])
|
||
{
|
||
[self setVersion: 3];
|
||
}
|
||
}
|
||
|
||
+ (EcAlarm*) alarmForManagedObject: (NSString*)managedObject
|
||
at: (NSDate*)eventDate
|
||
withEventType: (EcAlarmEventType)eventType
|
||
probableCause: (EcAlarmProbableCause)probableCause
|
||
specificProblem: (NSString*)specificProblem
|
||
perceivedSeverity: (EcAlarmSeverity)perceivedSeverity
|
||
proposedRepairAction: (NSString*)proposedRepairAction
|
||
additionalText: (NSString*)additionalText
|
||
{
|
||
EcAlarm *a = [self alloc];
|
||
|
||
a = [a initForManagedObject: managedObject
|
||
at: eventDate
|
||
withEventType: eventType
|
||
probableCause: probableCause
|
||
specificProblem: specificProblem
|
||
perceivedSeverity: perceivedSeverity
|
||
proposedRepairAction: proposedRepairAction
|
||
additionalText: additionalText];
|
||
return [a autorelease];
|
||
}
|
||
|
||
+ (EcAlarmEventType) eventTypeFromProbableCause: (EcAlarmProbableCause)value
|
||
{
|
||
switch (value)
|
||
{
|
||
case EcAlarmProbableCauseUnknown: // Don't call with this value
|
||
return EcAlarmEventTypeUnknown;
|
||
|
||
case EcAlarmCallEstablishmentError:
|
||
case EcAlarmCommunicationsProtocolError:
|
||
case EcAlarmCommunicationsSubsystemFailure:
|
||
case EcAlarmDegradedSignal:
|
||
case EcAlarmDTE_DCEInterfaceError:
|
||
case EcAlarmFramingError:
|
||
case EcAlarmLANError:
|
||
case EcAlarmLocalNodeTransmissionError:
|
||
case EcAlarmLossOfFrame:
|
||
case EcAlarmLossOfSignal:
|
||
case EcAlarmRemoteNodeTransmissionError:
|
||
return EcAlarmEventTypeCommunications;
|
||
|
||
case EcAlarmEnclosureDoorOpen:
|
||
case EcAlarmExcessiveVibration:
|
||
case EcAlarmFireDetected:
|
||
case EcAlarmFloodDetected:
|
||
case EcAlarmHeatingOrVentilationOrCoolingSystemProblem:
|
||
case EcAlarmHumidityUnacceptable:
|
||
case EcAlarmLeakDetected:
|
||
case EcAlarmMaterialSupplyExhausted:
|
||
case EcAlarmPressureUnacceptable:
|
||
case EcAlarmPumpFailure:
|
||
case EcAlarmTemperatureUnacceptable:
|
||
case EcAlarmToxicLeakDetected:
|
||
return EcAlarmEventTypeEnvironmental;
|
||
|
||
case EcAlarmAdapterError:
|
||
case EcAlarmDataSetOrModemError:
|
||
case EcAlarmEquipmentMalfunction:
|
||
case EcAlarmInputDeviceError:
|
||
case EcAlarmInputOutputDeviceError:
|
||
case EcAlarmMultiplexerProblem:
|
||
case EcAlarmOutputDeviceError:
|
||
case EcAlarmPowerProblem:
|
||
case EcAlarmProcessorProblem:
|
||
case EcAlarmReceiveFailure:
|
||
case EcAlarmReceiverFailure:
|
||
case EcAlarmTimingProblem:
|
||
case EcAlarmTransmitFailure:
|
||
case EcAlarmTransmitterFailure:
|
||
return EcAlarmEventTypeEquipment;
|
||
|
||
case EcAlarmApplicationSubsystemFailure:
|
||
case EcAlarmConfigurationOrCustomizationError:
|
||
case EcAlarmCorruptData:
|
||
case EcAlarmCpuCyclesLimitExceeded:
|
||
case EcAlarmFileError:
|
||
case EcAlarmOutOfMemory:
|
||
case EcAlarmSoftwareProgramAbnormallyTerminated:
|
||
case EcAlarmSoftwareProgramError:
|
||
case EcAlarmStorageCapacityProblem:
|
||
case EcAlarmUnderlyingResourceUnavailable:
|
||
case EcAlarmVersionMismatch:
|
||
return EcAlarmEventTypeProcessingError;
|
||
|
||
case EcAlarmBandwidthReduced:
|
||
case EcAlarmCongestion:
|
||
case EcAlarmPerformanceDegraded:
|
||
case EcAlarmQueueSizeExceeded:
|
||
case EcAlarmResourceAtOrNearingCapacity:
|
||
case EcAlarmResponseTimeExcessive:
|
||
case EcAlarmRetransmissionRateExcessive:
|
||
case EcAlarmThresholdCrossed:
|
||
return EcAlarmEventTypeQualityOfService;
|
||
}
|
||
return EcAlarmEventTypeUnknown;
|
||
}
|
||
|
||
+ (NSString*) stringFromEventType: (EcAlarmEventType)value
|
||
{
|
||
switch (value)
|
||
{
|
||
case EcAlarmEventTypeUnknown: // Not legal
|
||
return nil;
|
||
case EcAlarmEventTypeCommunications:
|
||
return @"communications";
|
||
case EcAlarmEventTypeEnvironmental:
|
||
return @"environmental";
|
||
case EcAlarmEventTypeEquipment:
|
||
return @"equipment";
|
||
case EcAlarmEventTypeProcessingError:
|
||
return @"processingError";
|
||
case EcAlarmEventTypeQualityOfService:
|
||
return @"qualityOfService";
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
+ (NSString*) stringFromProbableCause: (EcAlarmProbableCause)value
|
||
{
|
||
switch (value)
|
||
{
|
||
case EcAlarmProbableCauseUnknown:
|
||
return @"ProbableCauseUnknown";
|
||
case EcAlarmAdapterError:
|
||
return @"adapterError";
|
||
case EcAlarmApplicationSubsystemFailure:
|
||
return @"applicationSubsystemFailure";
|
||
case EcAlarmBandwidthReduced:
|
||
return @"bandwidthReduced";
|
||
case EcAlarmCallEstablishmentError:
|
||
return @"callEstablishmentError";
|
||
case EcAlarmCommunicationsProtocolError:
|
||
return @"communicationsProtocolError";
|
||
case EcAlarmCommunicationsSubsystemFailure:
|
||
return @"communicationsSubsystemFailure";
|
||
case EcAlarmConfigurationOrCustomizationError:
|
||
return @"configurationOrCustomizationError";
|
||
case EcAlarmCongestion:
|
||
return @"congestion";
|
||
case EcAlarmCorruptData:
|
||
return @"corruptData";
|
||
case EcAlarmCpuCyclesLimitExceeded:
|
||
return @"cpuCyclesLimitExceeded";
|
||
case EcAlarmDataSetOrModemError:
|
||
return @"dataSetOrModemError";
|
||
case EcAlarmDegradedSignal:
|
||
return @"degradedSignal";
|
||
case EcAlarmDTE_DCEInterfaceError:
|
||
return @"dTE-DCEInterfaceError";
|
||
case EcAlarmEnclosureDoorOpen:
|
||
return @"enclosureDoorOpen";
|
||
case EcAlarmEquipmentMalfunction:
|
||
return @"equipmentMalfunction";
|
||
case EcAlarmExcessiveVibration:
|
||
return @"excessiveVibration";
|
||
case EcAlarmFileError:
|
||
return @"fileError";
|
||
case EcAlarmFireDetected:
|
||
return @"fireDetected";
|
||
case EcAlarmFloodDetected:
|
||
return @"floodDetected";
|
||
case EcAlarmFramingError:
|
||
return @"framingError";
|
||
case EcAlarmHeatingOrVentilationOrCoolingSystemProblem:
|
||
return @"heatingOrVentilationOrCoolingSystemProblem";
|
||
case EcAlarmHumidityUnacceptable:
|
||
return @"humidityUnacceptable";
|
||
case EcAlarmInputOutputDeviceError:
|
||
return @"inputOutputDeviceError";
|
||
case EcAlarmInputDeviceError:
|
||
return @"inputDeviceError";
|
||
case EcAlarmLANError:
|
||
return @"lANError";
|
||
case EcAlarmLeakDetected:
|
||
return @"leakDetected";
|
||
case EcAlarmLocalNodeTransmissionError:
|
||
return @"localNodeTransmissionError";
|
||
case EcAlarmLossOfFrame:
|
||
return @"lossOfFrame";
|
||
case EcAlarmLossOfSignal:
|
||
return @"lossOfSignal";
|
||
case EcAlarmMaterialSupplyExhausted:
|
||
return @"materialSupplyExhausted";
|
||
case EcAlarmMultiplexerProblem:
|
||
return @"multiplexerProblem";
|
||
case EcAlarmOutOfMemory:
|
||
return @"outOfMemory";
|
||
case EcAlarmOutputDeviceError:
|
||
return @"outputDeviceError";
|
||
case EcAlarmPerformanceDegraded:
|
||
return @"performanceDegraded";
|
||
case EcAlarmPowerProblem:
|
||
return @"powerProblem";
|
||
case EcAlarmPressureUnacceptable:
|
||
return @"pressureUnacceptable";
|
||
case EcAlarmProcessorProblem:
|
||
return @"processorProblem";
|
||
case EcAlarmPumpFailure:
|
||
return @"pumpFailure";
|
||
case EcAlarmQueueSizeExceeded:
|
||
return @"queueSizeExceeded";
|
||
case EcAlarmReceiveFailure:
|
||
return @"receiveFailure";
|
||
case EcAlarmReceiverFailure:
|
||
return @"receiverFailure";
|
||
case EcAlarmRemoteNodeTransmissionError:
|
||
return @"remoteNodeTransmissionError";
|
||
case EcAlarmResourceAtOrNearingCapacity:
|
||
return @"resourceAtOrNearingCapacity";
|
||
case EcAlarmResponseTimeExcessive:
|
||
return @"responseTimeExcessive";
|
||
case EcAlarmRetransmissionRateExcessive:
|
||
return @"retransmissionRateExcessive";
|
||
case EcAlarmSoftwareProgramAbnormallyTerminated:
|
||
return @"softwareProgramAbnormallyTerminated";
|
||
case EcAlarmSoftwareProgramError:
|
||
return @"softwareProgramError";
|
||
case EcAlarmStorageCapacityProblem:
|
||
return @"storageCapacityProblem";
|
||
case EcAlarmTemperatureUnacceptable:
|
||
return @"temperatureUnacceptable";
|
||
case EcAlarmThresholdCrossed:
|
||
return @"thresholdCrossed";
|
||
case EcAlarmTimingProblem:
|
||
return @"timingProblem";
|
||
case EcAlarmToxicLeakDetected:
|
||
return @"toxicLeakDetected";
|
||
case EcAlarmTransmitFailure:
|
||
return @"transmitFailure";
|
||
case EcAlarmTransmitterFailure:
|
||
return @"transmitterFailure";
|
||
case EcAlarmUnderlyingResourceUnavailable:
|
||
return @"underlyingResourceUnavailable";
|
||
case EcAlarmVersionMismatch:
|
||
return @"versionMismatch";
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
+ (NSString*) stringFromSeverity: (EcAlarmSeverity)value
|
||
{
|
||
switch (value)
|
||
{
|
||
case EcAlarmSeverityIndeterminate: return @"indeterminate";
|
||
case EcAlarmSeverityCritical: return @"critical";
|
||
case EcAlarmSeverityMajor: return @"major";
|
||
case EcAlarmSeverityMinor: return @"minor";
|
||
case EcAlarmSeverityWarning: return @"warning";
|
||
case EcAlarmSeverityCleared: return @"cleared";
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
+ (NSString*) stringFromTrend: (EcAlarmTrend)value
|
||
{
|
||
switch (value)
|
||
{
|
||
case EcAlarmTrendNone: return @"none";
|
||
case EcAlarmTrendUp: return @"up";
|
||
case EcAlarmTrendDown: return @"down";
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (NSString*) additionalText
|
||
{
|
||
return _additionalText;
|
||
}
|
||
|
||
- (BOOL) audit
|
||
{
|
||
return _audit;
|
||
}
|
||
|
||
- (Class) classForCoder
|
||
{
|
||
return [EcAlarm class];
|
||
}
|
||
|
||
- (EcAlarm*) clear
|
||
{
|
||
EcAlarm *c = [self copy];
|
||
|
||
c->_perceivedSeverity = EcAlarmSeverityCleared;
|
||
c->_notificationID = _notificationID;
|
||
return [c autorelease];
|
||
}
|
||
|
||
- (NSComparisonResult) compare: (EcAlarm*)other
|
||
{
|
||
int oNotificationID;
|
||
NSString *sStr;
|
||
NSString *oStr;
|
||
|
||
if (NO == [other isKindOfClass: [EcAlarm class]])
|
||
{
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"[%@-%@] argument is not an EcAlarm",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
oNotificationID = [other notificationID];
|
||
if (_notificationID > 0 && oNotificationID > 0)
|
||
{
|
||
if (_notificationID < oNotificationID)
|
||
{
|
||
return NSOrderedAscending;
|
||
}
|
||
if (_notificationID > oNotificationID)
|
||
{
|
||
return NSOrderedDescending;
|
||
}
|
||
return NSOrderedSame;
|
||
}
|
||
sStr = [NSString stringWithFormat: @"%@ %d %d %@",
|
||
[self managedObject],
|
||
[self eventType],
|
||
[self probableCause],
|
||
[self specificProblem]];
|
||
oStr = [NSString stringWithFormat: @"%@ %d %d %@",
|
||
[other managedObject],
|
||
[other eventType],
|
||
[other probableCause],
|
||
[other specificProblem]];
|
||
return [sStr compare: oStr];
|
||
}
|
||
|
||
- (id) copyWithZone: (NSZone*)aZone
|
||
{
|
||
EcAlarm *c = [[self class] allocWithZone: aZone];
|
||
|
||
c = [c initForManagedObject: _managedObject
|
||
at: _eventDate
|
||
withEventType: _eventType
|
||
probableCause: _probableCause
|
||
specificProblem: _specificProblem
|
||
perceivedSeverity: _perceivedSeverity
|
||
proposedRepairAction: _proposedRepairAction
|
||
additionalText: _additionalText];
|
||
if (nil != c)
|
||
{
|
||
c->_firstEventDate = [_firstEventDate copyWithZone: aZone];
|
||
c->_notificationID = _notificationID;
|
||
c->_trendIndicator = _trendIndicator;
|
||
c->_delay = _delay;
|
||
ASSIGNCOPY(c->_userInfo, _userInfo);
|
||
}
|
||
return c;
|
||
}
|
||
|
||
- (void) dealloc
|
||
{
|
||
DESTROY(_userInfo);
|
||
DESTROY(_managedObject);
|
||
DESTROY(_eventDate);
|
||
DESTROY(_firstEventDate);
|
||
DESTROY(_specificProblem);
|
||
DESTROY(_proposedRepairAction);
|
||
DESTROY(_additionalText);
|
||
[super dealloc];
|
||
}
|
||
|
||
- (uint8_t) delay
|
||
{
|
||
return _delay;
|
||
}
|
||
|
||
- (BOOL) delayed: (NSTimeInterval)at
|
||
{
|
||
if (_delay > 0)
|
||
{
|
||
if (at < [_eventDate timeIntervalSinceReferenceDate] + _delay)
|
||
{
|
||
return YES;
|
||
}
|
||
}
|
||
return NO;
|
||
}
|
||
|
||
- (NSString*) description
|
||
{
|
||
NSMutableString *s = [NSMutableString stringWithCapacity: 1000];
|
||
Class c = [self class];
|
||
|
||
if (0 == _notificationID)
|
||
{
|
||
[s appendString: _(@"Alarm address")];
|
||
[s appendFormat: @": 0x%"PRIxPTR", ", (uintptr_t)self];
|
||
}
|
||
else
|
||
{
|
||
[s appendString: _(@"Alarm notification ID")];
|
||
[s appendFormat: @": %d, ", _notificationID];
|
||
}
|
||
|
||
[s appendString: _(@"Managed object")];
|
||
[s appendFormat: @": %@, ", _managedObject];
|
||
[s appendString: _(@"Type")];
|
||
[s appendFormat: @": %@, ", [c stringFromEventType: _eventType]];
|
||
[s appendString: _(@"Cause")];
|
||
[s appendFormat: @": %@, ", [c stringFromProbableCause: _probableCause]];
|
||
[s appendString: _(@"Severity")];
|
||
[s appendFormat: @": %@, ", [c stringFromSeverity: _perceivedSeverity]];
|
||
[s appendString: _(@"Timestamp")];
|
||
[s appendFormat: @": %@, ", _eventDate];
|
||
if (EcAlarmTrendNone !=_trendIndicator)
|
||
{
|
||
[s appendString: _(@"Trend")];
|
||
[s appendFormat: @": %@", [c stringFromTrend: _trendIndicator]];
|
||
if (nil != _firstEventDate
|
||
&& NO == [_firstEventDate isEqual: _eventDate])
|
||
{
|
||
[s appendString: @" "];
|
||
[s appendString: _(@"since")];
|
||
[s appendString: @" "];
|
||
[s appendString: [_firstEventDate description]];
|
||
}
|
||
[s appendString: @", "];
|
||
}
|
||
[s appendString: _(@"Problem")];
|
||
[s appendString: @": "];
|
||
[s appendString: _specificProblem];
|
||
if ([_additionalText length] > 0)
|
||
{
|
||
[s appendString: @": "];
|
||
[s appendString: _additionalText];
|
||
}
|
||
[s appendString: @", "];
|
||
[s appendString: _(@"Proposed repair action")];
|
||
[s appendString: @": "];
|
||
[s appendString: _proposedRepairAction];
|
||
|
||
return s;
|
||
}
|
||
|
||
- (void) encodeWithCoder: (NSCoder*)aCoder
|
||
{
|
||
[aCoder encodeValuesOfObjCTypes: "iiiii@@@@@@@c",
|
||
&_eventType,
|
||
&_notificationID,
|
||
&_perceivedSeverity,
|
||
&_probableCause,
|
||
&_trendIndicator,
|
||
&_managedObject,
|
||
&_eventDate,
|
||
&_firstEventDate,
|
||
&_specificProblem,
|
||
&_proposedRepairAction,
|
||
&_additionalText,
|
||
&_userInfo,
|
||
&_audit];
|
||
}
|
||
|
||
- (NSDate*) eventDate
|
||
{
|
||
return _eventDate;
|
||
}
|
||
|
||
- (EcAlarmEventType) eventType
|
||
{
|
||
return _eventType;
|
||
}
|
||
|
||
- (void *) extra
|
||
{
|
||
return _extra;
|
||
}
|
||
|
||
- (NSDate*) firstEventDate
|
||
{
|
||
return _firstEventDate;
|
||
}
|
||
|
||
- (void) freeze
|
||
{
|
||
/* NB this value must NOT be archived ... because when we restore from
|
||
* archive we will want to store a pointer in _extra.
|
||
*/
|
||
_frozen = YES;
|
||
}
|
||
|
||
- (NSUInteger) hash
|
||
{
|
||
return [_managedObject hash];
|
||
}
|
||
|
||
- (id) init
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"Called -init on EcAlarm"];
|
||
return nil;
|
||
}
|
||
|
||
- (id) initForManagedObject: (NSString*)managedObject
|
||
at: (NSDate*)eventDate
|
||
withEventType: (EcAlarmEventType)eventType
|
||
probableCause: (EcAlarmProbableCause)probableCause
|
||
specificProblem: (NSString*)specificProblem
|
||
perceivedSeverity: (EcAlarmSeverity)perceivedSeverity
|
||
proposedRepairAction: (NSString*)proposedRepairAction
|
||
additionalText: (NSString*)additionalText
|
||
{
|
||
Class c = [self class];
|
||
|
||
if (nil == managedObject)
|
||
{
|
||
managedObject = EcMakeManagedObject(nil, nil, nil);
|
||
}
|
||
if (4 != [[managedObject componentsSeparatedByString: @"_"] count])
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"bad managed object (%@)", managedObject];
|
||
}
|
||
if (127 < strlen([managedObject UTF8String]))
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"managed object too long (over 127 bytes): (%@)",
|
||
managedObject];
|
||
}
|
||
if (0 == [specificProblem length])
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"empty specific problem"];
|
||
}
|
||
if (255 < strlen([specificProblem UTF8String]))
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"specific problem too long (over 255 bytes): (%@)",
|
||
specificProblem];
|
||
}
|
||
if (0 == [proposedRepairAction length])
|
||
{
|
||
if (EcAlarmSeverityCleared == perceivedSeverity)
|
||
{
|
||
/* We don't need a proposed repair action for a clear.
|
||
*/
|
||
proposedRepairAction = @"";
|
||
}
|
||
else
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"empty proposed repair action"];
|
||
}
|
||
}
|
||
if (255 < strlen([proposedRepairAction UTF8String]))
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"proposed repair action too long (over 255 bytes): (%@)",
|
||
proposedRepairAction];
|
||
}
|
||
if (nil == eventDate)
|
||
{
|
||
eventDate = [NSDate date];
|
||
}
|
||
if (nil == additionalText)
|
||
{
|
||
additionalText = @"";
|
||
}
|
||
if (255 < strlen([additionalText UTF8String]))
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"additional text too long (over 255 bytes): (%@)",
|
||
additionalText];
|
||
}
|
||
if (nil == [c stringFromEventType: eventType])
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"bad event type (%d)", eventType];
|
||
}
|
||
if (nil == [c stringFromSeverity: perceivedSeverity])
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"bad severity (%d)", perceivedSeverity];
|
||
}
|
||
if (nil == [c stringFromProbableCause: probableCause])
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"bad probable cause (%d)", probableCause];
|
||
}
|
||
/* Anything other than an unknown probable cause must correspond to a
|
||
* known event type, but an unknown probable cause may match any event.
|
||
*/
|
||
if (EcAlarmProbableCauseUnknown != probableCause)
|
||
{
|
||
_eventType = [c eventTypeFromProbableCause: probableCause];
|
||
if (_eventType != eventType)
|
||
{
|
||
[self release];
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"missmatch of event type and probable cause"];
|
||
}
|
||
}
|
||
|
||
if (nil != (self = [super init]))
|
||
{
|
||
_notificationID = 0;
|
||
_eventType = eventType;
|
||
_perceivedSeverity = perceivedSeverity;
|
||
_probableCause = probableCause;
|
||
_trendIndicator = 0;
|
||
ASSIGNCOPY(_managedObject, managedObject);
|
||
ASSIGNCOPY(_eventDate, eventDate);
|
||
ASSIGNCOPY(_specificProblem, specificProblem);
|
||
ASSIGNCOPY(_proposedRepairAction, proposedRepairAction);
|
||
ASSIGNCOPY(_additionalText, additionalText);
|
||
}
|
||
return self;
|
||
}
|
||
|
||
- (id) initWithCoder: (NSCoder*)aCoder
|
||
{
|
||
int version = [aCoder versionForClassName: @"EcAlarm"];
|
||
|
||
if (version < 2)
|
||
{
|
||
[aCoder decodeValuesOfObjCTypes: "iiiii@@@@@@",
|
||
&_eventType,
|
||
&_notificationID,
|
||
&_perceivedSeverity,
|
||
&_probableCause,
|
||
&_trendIndicator,
|
||
&_managedObject,
|
||
&_eventDate,
|
||
&_firstEventDate,
|
||
&_specificProblem,
|
||
&_proposedRepairAction,
|
||
&_additionalText];
|
||
}
|
||
else if (version < 3)
|
||
{
|
||
[aCoder decodeValuesOfObjCTypes: "iiiii@@@@@@@",
|
||
&_eventType,
|
||
&_notificationID,
|
||
&_perceivedSeverity,
|
||
&_probableCause,
|
||
&_trendIndicator,
|
||
&_managedObject,
|
||
&_eventDate,
|
||
&_firstEventDate,
|
||
&_specificProblem,
|
||
&_proposedRepairAction,
|
||
&_additionalText,
|
||
&_userInfo];
|
||
}
|
||
else
|
||
{
|
||
[aCoder decodeValuesOfObjCTypes: "iiiii@@@@@@@c",
|
||
&_eventType,
|
||
&_notificationID,
|
||
&_perceivedSeverity,
|
||
&_probableCause,
|
||
&_trendIndicator,
|
||
&_managedObject,
|
||
&_eventDate,
|
||
&_firstEventDate,
|
||
&_specificProblem,
|
||
&_proposedRepairAction,
|
||
&_additionalText,
|
||
&_userInfo,
|
||
&_audit];
|
||
}
|
||
return self;
|
||
}
|
||
|
||
/* Return YES if the two instances are equal according to the correlation
|
||
* rules, NO otherwise.
|
||
*/
|
||
- (BOOL) isEqual: (id)other
|
||
{
|
||
if (other == self)
|
||
{
|
||
return YES;
|
||
}
|
||
if (NO == [other isKindOfClass: [EcAlarm class]])
|
||
{
|
||
return NO;
|
||
}
|
||
if (NO == [[other managedObject] isEqual: _managedObject])
|
||
{
|
||
return NO;
|
||
}
|
||
if (_notificationID > 0 && [other notificationID] == _notificationID)
|
||
{
|
||
/* We have a notificationID set ... if both have the same notification
|
||
* ID then they are the same.
|
||
*/
|
||
return YES;
|
||
}
|
||
|
||
/* The correlation rule normally is:
|
||
* Same managed object
|
||
* same event type
|
||
* same probable cause
|
||
* same specific problem
|
||
*/
|
||
if ([other eventType] == _eventType
|
||
&& [other probableCause] == _probableCause
|
||
&& [[other specificProblem] isEqual: _specificProblem])
|
||
{
|
||
return YES;
|
||
}
|
||
return NO;
|
||
}
|
||
|
||
- (NSString*) managedObject
|
||
{
|
||
return _managedObject;
|
||
}
|
||
|
||
- (NSString*) moComponent
|
||
{
|
||
NSArray *s = [_managedObject componentsSeparatedByString: @"_"];
|
||
|
||
return [s objectAtIndex: 3];
|
||
}
|
||
|
||
- (NSString*) moHost
|
||
{
|
||
NSArray *s = [_managedObject componentsSeparatedByString: @"_"];
|
||
|
||
return [s objectAtIndex: 0];
|
||
}
|
||
|
||
- (NSString*) moInstance
|
||
{
|
||
NSArray *s = [_managedObject componentsSeparatedByString: @"_"];
|
||
|
||
return [s objectAtIndex: 2];
|
||
}
|
||
|
||
- (NSString*) moInstancedProcess
|
||
{
|
||
NSArray *s = [_managedObject componentsSeparatedByString: @"_"];
|
||
NSString *i = [s objectAtIndex: 2];
|
||
|
||
if ([i length] > 0)
|
||
{
|
||
return [NSString stringWithFormat: @"%@-%@", [s objectAtIndex: 1], i];
|
||
}
|
||
return [s objectAtIndex: 1];
|
||
}
|
||
|
||
- (NSString*) moProcess
|
||
{
|
||
NSArray *s = [_managedObject componentsSeparatedByString: @"_"];
|
||
|
||
return [s objectAtIndex: 1];
|
||
}
|
||
|
||
- (int) notificationID
|
||
{
|
||
return _notificationID;
|
||
}
|
||
|
||
- (EcAlarmSeverity) perceivedSeverity
|
||
{
|
||
return _perceivedSeverity;
|
||
}
|
||
|
||
- (NSString*) proposedRepairAction
|
||
{
|
||
return _proposedRepairAction;
|
||
}
|
||
|
||
- (EcAlarmProbableCause) probableCause
|
||
{
|
||
return _probableCause;
|
||
}
|
||
|
||
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder
|
||
{
|
||
return self;
|
||
}
|
||
|
||
- (void) setAudit: (BOOL)flag
|
||
{
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
_audit = (flag ? YES : NO);
|
||
}
|
||
|
||
- (void) setDelay: (uint8_t)delay
|
||
{
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
_delay = delay;
|
||
}
|
||
|
||
- (void) setExtra: (void*)extra
|
||
{
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
_extra = extra;
|
||
}
|
||
|
||
- (void) setFirstEventDate: (NSDate*)firstEventDate
|
||
{
|
||
if (nil != firstEventDate
|
||
&& NO == [firstEventDate isKindOfClass: [NSDate class]])
|
||
{
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"[%@-%@] bad argument '%@'",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd),
|
||
firstEventDate];
|
||
}
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
ASSIGNCOPY(_firstEventDate, firstEventDate);
|
||
}
|
||
|
||
- (void) setNotificationID: (int)notificationID
|
||
{
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
_notificationID = notificationID;
|
||
}
|
||
|
||
- (void) setTrendIndicator: (EcAlarmTrend)trendIndicator
|
||
{
|
||
if (nil == [[self class] stringFromTrend: trendIndicator])
|
||
{
|
||
[NSException raise: NSInvalidArgumentException
|
||
format: @"[%@-%@] bad argument '%d'",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd),
|
||
trendIndicator];
|
||
}
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
_trendIndicator = trendIndicator;
|
||
}
|
||
|
||
- (void) setUserInfo: (NSDictionary*)userInfo
|
||
{
|
||
if (YES == _frozen)
|
||
{
|
||
[NSException raise: NSInternalInconsistencyException
|
||
format: @"[%@-%@] called for frozen instance",
|
||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||
}
|
||
ASSIGNCOPY(_userInfo, userInfo);
|
||
}
|
||
|
||
- (NSString*) specificProblem
|
||
{
|
||
return _specificProblem;
|
||
}
|
||
|
||
- (EcAlarmTrend) trendIndicator
|
||
{
|
||
return _trendIndicator;
|
||
}
|
||
|
||
- (NSDictionary*) userInfo
|
||
{
|
||
return _userInfo;
|
||
}
|
||
|
||
@end
|
||
|
||
|
||
@implementation EcAlarm (Convenience)
|
||
|
||
+ (EcAlarm*) clear: (NSString*)componentName
|
||
cause: (EcAlarmProbableCause)probableCause
|
||
problem: (NSString*)specificProblem
|
||
{
|
||
NSString *managedObject;
|
||
EcAlarmEventType eventType;
|
||
|
||
managedObject = EcMakeManagedObject(nil, nil, componentName);
|
||
eventType = [self eventTypeFromProbableCause: probableCause];
|
||
return [self alarmForManagedObject: managedObject
|
||
at: nil
|
||
withEventType: eventType
|
||
probableCause: probableCause
|
||
specificProblem: specificProblem
|
||
perceivedSeverity: EcAlarmSeverityCleared
|
||
proposedRepairAction: nil
|
||
additionalText: nil];
|
||
}
|
||
|
||
+ (EcAlarm*) raise: (NSString*)componentName
|
||
cause: (EcAlarmProbableCause)probableCause
|
||
problem: (NSString*)specificProblem
|
||
severity: (EcAlarmSeverity)perceivedSeverity
|
||
action: (NSString*)proposedRepairAction,...
|
||
{
|
||
NSString *managedObject;
|
||
EcAlarmEventType eventType;
|
||
NSString *mesg;
|
||
va_list ap;
|
||
|
||
NSAssert(EcAlarmSeverityCleared != perceivedSeverity,
|
||
NSInvalidArgumentException);
|
||
|
||
managedObject = EcMakeManagedObject(nil, nil, componentName);
|
||
eventType = [self eventTypeFromProbableCause: probableCause];
|
||
|
||
va_start (ap, proposedRepairAction);
|
||
mesg = [NSString stringWithFormat: proposedRepairAction arguments: ap];
|
||
va_end (ap);
|
||
return [self alarmForManagedObject: managedObject
|
||
at: nil
|
||
withEventType: eventType
|
||
probableCause: probableCause
|
||
specificProblem: specificProblem
|
||
perceivedSeverity: perceivedSeverity
|
||
proposedRepairAction: mesg
|
||
additionalText: nil];
|
||
}
|
||
|
||
@end
|
||
|