blob: 8801912c6698885db61f7b35491db2e020b879e0 [file] [log] [blame]
/*
* Copyright 1996-2011 Niclas Hedhman.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied.
*
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.zest.library.alarm;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
import org.apache.zest.api.entity.Identity;
import org.apache.zest.api.injection.scope.Structure;
import org.apache.zest.api.mixin.Mixins;
import org.apache.zest.api.service.ServiceComposite;
import org.apache.zest.api.value.ValueBuilder;
import org.apache.zest.api.value.ValueBuilderFactory;
/**
* The Standard Model is centered around the Normal, Activated, Acknowledged
* Deactivated, Reactivated, Blocked and Disabled states, and the triggers "activate", "deactivate",
* "acknowledge", "block", "unblock", "enable" and "disable". The following matrix details the
* resulting grid.
* <table summary="Transitions">
* <tr><th>Initial State</th><th>Trigger</th><th>Resulting State</th><th>Event Generated</th></tr>
* <tr><td>Normal</td><td>activate</td><td>Activated</td><td>activation</td></tr>
* <tr><td>Normal</td><td>deactivate</td><td>Normal</td><td>-</td></tr>
* <tr><td>Normal</td><td>acknowledge</td><td>Normal</td><td>-</td></tr>
* <tr><td>Normal</td><td>block</td><td>Blocked</td><td>block</td></tr>
* <tr><td>Normal</td><td>unblock</td><td>Normal</td><td>-</td></tr>
* <tr><td>Activated</td><td>activate</td><td>Activated</td><td>-</td></tr>
* <tr><td>Activated</td><td>deactivate</td><td>Deactivated</td><td>deactivation</td></tr>
* <tr><td>Activated</td><td>acknowledge</td><td>Acknowledged</td><td>acknowledge</td></tr>
* <tr><td>Activated</td><td>block</td><td>Blocked</td><td>block</td></tr>
* <tr><td>Activated</td><td>unblock</td><td>Activated</td><td>-</td></tr>
* <tr><td>Deactivated</td><td>activate</td><td>Activated</td><td>activation</td></tr>
* <tr><td>Deactivated</td><td>deactivate</td><td>Deativated</td><td>-</td></tr>
* <tr><td>Deactivated</td><td>acknowledge</td><td>Normal</td><td>acknowledge</td></tr>
* <tr><td>Deactivated</td><td>block</td><td>Blocked</td><td>block</td></tr>
* <tr><td>Deactivated</td><td>unblock</td><td>Deactivated</td><td>-</td></tr>
* <tr><td>Acknowledged</td><td>activate</td><td>Acknowledged</td><td>-</td></tr>
* <tr><td>Acknowledged</td><td>deactivate</td><td>Normal</td><td>deactivation</td></tr>
* <tr><td>Acknowledged</td><td>acknowledge</td><td>Acknowledged</td><td>-</td></tr>
* <tr><td>Acknowledged</td><td>block</td><td>Blocked</td><td>block</td></tr>
* <tr><td>Acknowledged</td><td>unblock</td><td>Acknowledged</td><td>-</td></tr>
* <tr><td>Blocked</td><td>activate</td><td>Blocked</td><td>-</td></tr>
* <tr><td>Blocked</td><td>deactivate</td><td>Blocked</td><td>-</td></tr>
* <tr><td>Blocked</td><td>acknowledge</td><td>Blocked</td><td>-</td></tr>
* <tr><td>Blocked</td><td>block</td><td>Blocked</td><td>-</td></tr>
* <tr><td>Blocked</td><td>unblock</td><td>Normal</td><td>unblock</td></tr>
* <tr><td>Normal</td><td>disable</td><td>Disabled</td><td>disable</td></tr>
* <tr><td>Blocked</td><td>disable</td><td>Disabled</td><td>disable</td></tr>
* <tr><td>Deactivated</td><td>disable</td><td>Disabled</td><td>disable</td></tr>
* <tr><td>Acknowledged</td><td>disable</td><td>Disabled</td><td>disable</td></tr>
* <tr><td>Activated</td><td>disable</td><td>Disabled</td><td>disable</td></tr>
* <tr><td>Reactivated</td><td>disable</td><td>Disabled</td><td>disable</td></tr>
* <tr><td>Disabled</td><td>disable</td><td>Disabled</td><td>-</td></tr>
* <tr><td>Normal</td><td>enable</td><td>Normal</td><td>-</td></tr>
* <tr><td>Blocked</td><td>enable</td><td>Blocked</td><td>-</td></tr>
* <tr><td>Deactivated</td><td>enable</td><td>Deactivated</td><td>-</td></tr>
* <tr><td>Acknowledged</td><td>enable</td><td>Acknowledged</td><td>-</td></tr>
* <tr><td>Activated</td><td>enable</td><td>Activated</td><td>-</td></tr>
* <tr><td>Reactivated</td><td>enable</td><td>Reactivated</td><td>-</td></tr>
* <tr><td>Disabled</td><td>enable</td><td>Normal</td><td>enable</td></tr>
* </table>
*/
@Mixins(ExtendedAlarmModelService.ExtendedAlarmModelMixin.class)
public interface ExtendedAlarmModelService
extends AlarmModel, ServiceComposite
{
class ExtendedAlarmModelMixin
implements AlarmModel
{
private final static List<String> TRIGGER_LIST;
private static final List<String> STATUS_LIST;
@Structure
private ValueBuilderFactory vbf;
static
{
List<String> list1 = new ArrayList<String>();
list1.add( AlarmPoint.STATUS_NORMAL );
list1.add( AlarmPoint.STATUS_ACTIVATED );
list1.add( AlarmPoint.STATUS_DEACTIVATED );
list1.add( AlarmPoint.STATUS_ACKNOWLEDGED );
list1.add( AlarmPoint.STATUS_REACTIVATED );
list1.add( AlarmPoint.STATUS_BLOCKED );
list1.add( AlarmPoint.STATUS_DISABLED );
STATUS_LIST = Collections.unmodifiableList( list1 );
List<String> list2 = new ArrayList<String>();
list2.add( AlarmPoint.TRIGGER_ACTIVATE );
list2.add( AlarmPoint.TRIGGER_DEACTIVATE );
list2.add( AlarmPoint.TRIGGER_ACKNOWLEDGE );
list2.add( AlarmPoint.TRIGGER_BLOCK );
list2.add( AlarmPoint.TRIGGER_UNBLOCK );
list2.add( AlarmPoint.TRIGGER_DISABLE);
list2.add( AlarmPoint.TRIGGER_ENABLE );
TRIGGER_LIST = Collections.unmodifiableList( list2 );
}
static ResourceBundle getResourceBundle( Locale locale )
{
if( locale == null )
{
locale = Locale.getDefault();
}
ClassLoader cl = ExtendedAlarmModelMixin.class.getClassLoader();
return ResourceBundle.getBundle( MODEL_BUNDLE_NAME, locale, cl );
}
/**
* Returns the Name of the AlarmModel.
* This normally returns the human readable technical name of
* the AlarmModel.
*
* @return The system name of this alarm model.
*/
@Override
public String modelName()
{
return "org.qi4j.library.alarm.model.extended";
}
/**
* Returns a Description of the AlarmModel in the default Locale.
* This normally returns a full Description of the AlarmModel in the
* default Locale.
*
* @return the description of the ModelProvider, in the default locale.
*/
@Override
public String modelDescription()
{
return modelDescription( null );
}
/**
* Returns a Description of the AlarmModel.
* This normally returns a full Description of the AlarmModel in the
* Locale. If Locale is <code><b>null</b></code>, then the
* default Locale is used.
*
* @param locale The locale that should be used for the description, or null for the default locale.
*
* @return The human readable, in the given locale, description of this alarm model.
*/
@Override
public String modelDescription( Locale locale )
{
ResourceBundle rb = getResourceBundle( locale );
return rb.getString( "MODEL_DESCRIPTION_EXTENDED" );
}
/**
* Execute the required changes upon an AlarmTrigger.
* The AlarmSystem calls this method, for the AlarmStatus
* in the the AlarmPoint to be updated, as well as an AlarmEvent
* to be created.
*
* @param alarm the AlarmPoint object to be updated.
* @param trigger the AlarmTrigger that was used.
*/
@Override
public AlarmEvent evaluate( AlarmPoint alarm, String trigger )
{
if( trigger.equals( AlarmPoint.TRIGGER_ACTIVATE ) )
{
return activation( alarm );
}
else if( trigger.equals( AlarmPoint.TRIGGER_DEACTIVATE ) )
{
return deactivation( alarm );
}
else if( trigger.equals( AlarmPoint.TRIGGER_ACKNOWLEDGE ) )
{
return acknowledge( alarm );
}
else if( trigger.equals( AlarmPoint.TRIGGER_BLOCK ) )
{
return block( alarm );
}
else if( trigger.equals( AlarmPoint.TRIGGER_UNBLOCK ) )
{
return unblock( alarm );
}
else if( trigger.equals( AlarmPoint.TRIGGER_ENABLE ) )
{
return enable( alarm );
}
else if( trigger.equals( AlarmPoint.TRIGGER_DISABLE ) )
{
return disable( alarm );
}
else
{
throw new IllegalArgumentException( "'" + trigger + "' is not supported by this AlarmModel." );
}
}
/**
* Returns all the supported AlarmPoint triggers.
*
* @return The AlarmPoint triggers that this AlarmModel supports.
*/
@Override
public List<String> alarmTriggers()
{
return TRIGGER_LIST;
}
@Override
public List<String> statusList()
{
return STATUS_LIST; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String computeTrigger( AlarmStatus status, boolean condition )
{
if( condition )
{
if( ( status.name(null).equals( AlarmPoint.STATUS_DEACTIVATED ) ) ||
( status.name(null).equals( AlarmPoint.STATUS_NORMAL ) ) )
{
return AlarmPoint.TRIGGER_ACTIVATE;
}
}
else
{
if( ( status.name(null).equals( AlarmPoint.STATUS_ACTIVATED ) ) ||
( status.name(null).equals( AlarmPoint.STATUS_REACTIVATED ) ) ||
( status.name(null).equals( AlarmPoint.STATUS_ACKNOWLEDGED ) ) )
{
return AlarmPoint.TRIGGER_DEACTIVATE;
}
}
return null;
}
@Override
public boolean computeCondition( AlarmStatus status )
{
return ( status.name(null).equals( AlarmPoint.STATUS_ACTIVATED ) ) ||
( status.name(null).equals( AlarmPoint.STATUS_REACTIVATED ) ) ||
( status.name(null).equals( AlarmPoint.STATUS_ACKNOWLEDGED ) );
}
/**
* StateMachine change for activate trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on activation.
*/
private AlarmEvent activation( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( ( status.name(null).equals( AlarmPoint.STATUS_NORMAL ) ) ||
( status.name(null).equals( AlarmPoint.STATUS_DEACTIVATED ) ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_ACTIVATED );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_ACTIVATION );
}
return null;
}
/**
* StateMachine change for activate trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on deactivation.
*/
private AlarmEvent deactivation( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( status.name(null).equals( AlarmPoint.STATUS_ACKNOWLEDGED ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_NORMAL );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_DEACTIVATION );
}
else if( status.name(null).equals( AlarmPoint.STATUS_ACTIVATED ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_DEACTIVATED );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_DEACTIVATION );
}
return null;
}
/**
* StateMachine change for activate trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on acknowledge.
*/
private AlarmEvent acknowledge( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( status.name(null).equals( AlarmPoint.STATUS_DEACTIVATED ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_NORMAL );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_ACKNOWLEDGEMENT );
}
else if( status.name(null).equals( AlarmPoint.STATUS_ACTIVATED ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_ACKNOWLEDGED );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_ACKNOWLEDGEMENT );
}
return null;
}
/**
* StateMachine change for block trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on acknowledge.
*/
private AlarmEvent block( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( status.name(null).equals( AlarmPoint.STATUS_BLOCKED ) ||
status.name(null).equals( AlarmPoint.STATUS_DISABLED ) )
{
return null;
}
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_BLOCKED );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_BLOCKING );
}
/**
* StateMachine change for unblock trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on acknowledge.
*/
private AlarmEvent unblock( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( status.name(null).equals( AlarmPoint.STATUS_BLOCKED ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_NORMAL );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_UNBLOCKING );
}
return null;
}
/**
* StateMachine change for disable trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on acknowledge.
*/
private AlarmEvent disable( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( status.name(null).equals( AlarmPoint.STATUS_DISABLED ) )
{
return null;
}
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_DISABLED );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_DISABLING );
}
/**
* StateMachine change for unblock trigger.
*
* @param alarm the alarm that is being triggered.
*
* @return The event to be fired on acknowledge.
*/
private AlarmEvent enable( AlarmPoint alarm )
{
AlarmStatus status = alarm.currentStatus();
if( status.name(null).equals( AlarmPoint.STATUS_DISABLED ) )
{
AlarmStatus newStatus = createStatus( AlarmPoint.STATUS_NORMAL );
return createEvent( ( (Identity) alarm ), status, newStatus, AlarmPoint.EVENT_ENABLING );
}
return null;
}
private AlarmStatus createStatus( String status )
{
ValueBuilder<AlarmStatus> builder = vbf.newValueBuilder( AlarmStatus.class );
AlarmStatus.State prototype = builder.prototypeFor(AlarmStatus.State.class);
prototype.name().set( status );
prototype.creationDate().set( new Date() );
return builder.newInstance();
}
private AlarmEvent createEvent( Identity alarmId,
AlarmStatus oldStatus,
AlarmStatus newStatus,
String eventSystemName
)
{
ValueBuilder<AlarmEvent> builder = vbf.newValueBuilder( AlarmEvent.class );
AlarmEvent prototype = builder.prototype();
prototype.alarmIdentity().set( alarmId.identity().get() );
prototype.eventTime().set( new Date() );
prototype.newStatus().set( newStatus );
prototype.oldStatus().set( oldStatus );
prototype.systemName().set( eventSystemName );
return builder.newInstance();
}
}
}