/*
Name:
- Plan
Description:
-
Requires:
-
Provides:
-
Part of: ProcessPuzzle Framework, Domain and Business Model Ready Architecture. Provides content, workflow and social networking functionality.
http://www.processpuzzle.com
ProcessPuzzle - Content and Workflow Management Integration Business Platform
Author(s):
- Zsolt Zsuffa
Copyright: (C) 2011 This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License as published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.processpuzzle.workflow.activity.domain;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import com.processpuzzle.fundamental_types.domain.TimePoint;
import com.processpuzzle.party.domain.Party;
import com.processpuzzle.party.partyrelationshiptype.domain.PartyRoleType;
import com.processpuzzle.persistence.query.domain.DefaultIdentityExpression;
import com.processpuzzle.persistence.query.domain.DefaultQueryContext;
import com.processpuzzle.util.domain.OPDomainStrings;
import com.processpuzzle.workflow.protocol.domain.ActivityProtocol;
import com.processpuzzle.workflow.protocol.domain.CompositeProtocol;
public class Plan<P extends Plan<?>> extends Action<P> {
private Set<ActionReference> actions = new HashSet<ActionReference>();
private Set<ProcessPlan> subProcessPlans = new HashSet<ProcessPlan>();
private PlanType type;
private Plan<?> parent;
public Plan( String name, CompositeProtocol protocol ) {
super( name, protocol );
}
public Plan( String name ) {
this( name, null );
}
protected Plan() {
this( null, null );
}
public void addSubProcessPlan( ProcessPlan subProcessPlan ) {
for( Iterator<ProcessPlan> i = subProcessPlans.iterator(); i.hasNext(); ){
Action<?> a = i.next();
if( a.getName().toLowerCase().equals( subProcessPlan.getName().toLowerCase() ) )
return;
}
subProcessPlans.add( subProcessPlan );
subProcessPlan.addPlan( this );
}
public void processComponentActionEvent( ActionEvent event ) {
if( event instanceof ActionImplementationEvent ){
if( event.getNextStatus() instanceof ImplementedStatus && !(this.getStatus() instanceof ImplementedStatus) ){
ActionEvent theEvent = new ActionImplementationEvent( OPDomainStrings.ACTION_EVENT_IMPLEMETATION, this, new ImplementedStatus(
OPDomainStrings.ACTION_STATUS_IMPLEMENTED ) );
theEvent.setOccuredOn( new TimePoint( new Date( System.currentTimeMillis() ) ) );
this.getActionEvents().add( theEvent );
changeStatus( theEvent );
}
}else if( event instanceof ActionEvent ){
if( event.getNextStatus() instanceof CompletedStatus && !(this.getStatus() instanceof CompletedStatus) ){
if( isComplete() ){
ActionEvent theEvent = new ActionCompletitionEvent( OPDomainStrings.ACTION_EVENT_COMPLETITION, this, new CompletedStatus(
OPDomainStrings.ACTION_STATUS_COMPLETED ) );
theEvent.setOccuredOn( new TimePoint( new Date( System.currentTimeMillis() ) ) );
this.getActionEvents().add( theEvent );
changeStatus( theEvent );
}
}
}
}
public boolean isComplete() {
boolean isComplete = true;
for( Iterator<?> iter = getSubActions().iterator(); iter.hasNext(); ){
Action<?> anAction = (Action<?>) iter.next();
if( !(anAction.getStatus() instanceof CompletedStatus && anAction.isMandatory()) ){
isComplete = false;
}
}
return isComplete;
}
public boolean hasOneSubAction() {
return(getSubActions().size() > 0);
}
public Collection<Action<?>> findLeafSubActions() {
Collection<Action<?>> leafs = new HashSet<Action<?>>();
for( Iterator<Action<?>> iter = this.getSubActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
if( action.isLeaf() )
leafs.add( action );
}
return leafs;
}
public Collection<Action<?>> findAllLeafActions() {
Collection<Action<?>> matches = new HashSet<Action<?>>();
Plan<?> temp = this;
matches.addAll( temp.findLeafSubActions() );
for( Iterator<?> iter = temp.getSubActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
if( action instanceof Plan ){
temp = (Plan<?>) action;
matches.addAll( temp.findLeafSubActions() );
}else{
matches.add( action );
}
continue;
}
return matches;
}
public Action<?> findFirstActionByTimePoint() {
Action<?> firstAction = null;
TimePoint bigTime = new TimePoint( new GregorianCalendar( 3000, 1, 1 ).getTime() );
for( Iterator<?> iter = getSubActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
if( action.getProjectedBegin().getValue().before( bigTime.getValue() ) ){
firstAction = action;
bigTime = action.getProjectedBegin();
}
}
return firstAction;
}
public Action<?> findLastActionByTimePoint() {
Action<?> lastAction = null;
TimePoint tinyTime = new TimePoint( new GregorianCalendar( 1000, 1, 1 ).getTime() );
for( Iterator<?> iter = getSubActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
if( action.getProjectedBegin().getValue().after( tinyTime.getValue() ) ){
lastAction = action;
tinyTime = action.getProjectedBegin();
}
}
return lastAction;
}
public void updateDefaultPerformerOfRole( PartyRoleType partyRoleType, Party<?> party ) {
for( Iterator<?> iter = findAllLeafActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
ActivityProtocol activityProtocol = (ActivityProtocol) action.getProtocol();
if( activityProtocol != null && activityProtocol.getPerformerRole().equals( partyRoleType ) )
action.setPerformer( party );
}
}
public void addSubAction( Action<?> action ) {
ActionReference anActionReference = new ActionReference( action, this );
action.getProjectPIncludedIn().add( anActionReference );
actions.add( anActionReference );
}
// Getters and setters
public List<PartyRoleType> getPartyRoleTypes() {
List<PartyRoleType> partyRoleTypes = new ArrayList<PartyRoleType>();
for( Iterator<?> iter = findAllLeafActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
ActivityProtocol activityProtocol = (ActivityProtocol) action.getProtocol();
if( activityProtocol != null && !partyRoleTypes.contains( activityProtocol.getPerformerRole() ) ){
partyRoleTypes.add( activityProtocol.getPerformerRole() );
}
}
return partyRoleTypes;
}
public Set<Action<?>> getSubActions() {
Set<Action<?>> subActions = new HashSet<Action<?>>();
for( Iterator<ActionReference> iter = actions.iterator(); iter.hasNext(); ){
ActionReference actionReference = (ActionReference) iter.next();
subActions.add( actionReference.getAction() );
}
return subActions;
}
@SuppressWarnings("unchecked")
public <T extends Action<?>> Set<T> getSubActionsGeneric( Class<T> c ) {
Set<T> subActions = new HashSet<T>();
for( Iterator<ActionReference> iter = actions.iterator(); iter.hasNext(); ){
ActionReference actionReference = (ActionReference) iter.next();
if( c.isInstance( actionReference.getAction() ) )
subActions.add( (T) actionReference.getAction() );
}
return subActions;
}
public Set<Plan<?>> getSubPlans() {
Set<Plan<?>> subActions = new HashSet<Plan<?>>();
for( Iterator<ActionReference> iter = actions.iterator(); iter.hasNext(); ){
ActionReference actionReference = (ActionReference) iter.next();
if( actionReference.getAction() instanceof Plan )
subActions.add( (Plan<?>) actionReference.getAction() );
}
return subActions;
}
public Set<Activity> getSubActivities() {
Set<Activity> subActions = new HashSet<Activity>();
for( Iterator<ActionReference> iter = actions.iterator(); iter.hasNext(); ){
ActionReference actionReference = (ActionReference) iter.next();
if( actionReference.getAction() instanceof Plan )
subActions.add( (Activity) actionReference.getAction() );
}
return subActions;
}
public Action<?> getSubActionByProtocolName( String name ) {
Action<?> match = null;
if( hasOneSubAction() ){
Plan<?> temp = this;
for( Iterator<?> iter = temp.getSubActions().iterator(); iter.hasNext(); ){
Action<?> action = (Action<?>) iter.next();
if( action.getProtocol().getName().equals( name ) ){
match = action;
break;
}else{
if( action instanceof Plan ){
Plan<?> plan = (Plan<?>) action;
temp = plan;
match = temp.getSubActionByProtocolName( name );
if( match != null )
break;
}
}
}
}
return match;
}
public Collection<GeneralResourceAllocation> getGeneralPartyRoleTypeAllocations() {
List<GeneralResourceAllocation> partyRoleTypeAllocations = new ArrayList<GeneralResourceAllocation>();
for( Iterator<Action<?>> iter = findAllLeafActions().iterator(); iter.hasNext(); ){
Action<?> action = iter.next();
Collection<GeneralResourceAllocation> genrealResources = action.getGeneralResourceAllocations();
for( Iterator<GeneralResourceAllocation> iterator = genrealResources.iterator(); iterator.hasNext(); ){
GeneralResourceAllocation resourceAllocation = iterator.next();
if( resourceAllocation.getPartyRoleType() != null )
partyRoleTypeAllocations.add( resourceAllocation );
}
}
return partyRoleTypeAllocations;
}
public Action<?> getLeafActionByName( String name ) {
Collection<?> leafs = this.findAllLeafActions();
for( Iterator<?> iterator = leafs.iterator(); iterator.hasNext(); ){
Action<?> action = (Action<?>) iterator.next();
if( action.getName().equals( name ) ){
return action;
}
}
return null;
}
public Set<ActionReference> getActions() {
return actions;
}
public Set<ProcessPlan> getSubProcessPlans() {
return subProcessPlans;
}
@Override
public TimePoint getProjectedBegin() {
Action<?> firstAction = findFirstActionByTimePoint();
return firstAction.getProjectedBegin();
}
@Override
public TimePoint getProjectedEnd() {
Action<?> lastAction = findLastActionByTimePoint();
return lastAction.getProjectedEnd();
}
@Override
public TimePoint getRealBegin() {
Action<?> action = findFirstActionByTimePoint();
if( action != null )
return action.getTimePeriod().getBegin();
else
return null;
}
@Override
public TimePoint getRealEnd() {
Action<?> lastAction = findLastActionByTimePoint();
if( lastAction != null )
return lastAction.getTimePeriod().getEnd();
else
return null;
}
public void setSubActions( Set<ActionReference> actions ) {
this.actions = actions;
}
public void setSubProcessPlans( Set<ProcessPlan> subProcessPlans ) {
this.subProcessPlans = subProcessPlans;
}
@Override
public void setProjectedBegin( TimePoint projectedBegin ) {
findFirstActionByTimePoint().setProjectedBegin( projectedBegin );
}
@Override
public void setProjectedEnd( TimePoint projectedEnd ) {
findLastActionByTimePoint().setProjectedEnd( projectedEnd );
}
@Override
public void setRealBegin( TimePoint realBegin ) {
Action<?> firstAction = findFirstActionByTimePoint();
firstAction.setRealBegin( realBegin );
}
@Override
public void setRealEnd( TimePoint realEnd ) {
Action<?> lastAction = findLastActionByTimePoint();
lastAction.setRealEnd( realEnd );
}
public PlanType getType() {
return type;
}
public void setType( SeparatePlan type ) {
this.type = type;
}
public void setType( PartPlan type, Plan<?> p ) {
p.addSubAction( this );
parent = p;
this.type = type;
}
public Plan<?> getParentPlan() {
return parent;
}
@SuppressWarnings( "unchecked" )
protected void defineIdentityExpressions() {
DefaultQueryContext context = new DefaultQueryContext();
defaultIdentity = (DefaultIdentityExpression<P>) new PlanIdentity( context );
identities.add( defaultIdentity );
}
@SuppressWarnings("unchecked")
@Override
public DefaultIdentityExpression getDefaultIdentity() {
return defaultIdentity;
}
}