首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

生命周期组件框架:生命周期描述语言——条件转移以及生命周期回调 示范

2013-12-04 
生命周期组件框架:生命周期描述语言——条件转移以及生命周期回调 示例@StateMachinepublic static interfac

生命周期组件框架:生命周期描述语言——条件转移以及生命周期回调 示例

    @StateMachine    public static interface InvoiceStateMachineMeta {        @StateSet        static interface States {            @Initial            @Function(transition = InvoiceStateMachineMeta.Transitions.Post.class, value = { InvoiceStateMachineMeta.States.Posted.class })            static interface Draft {}            @Functions({ @Function(transition = InvoiceStateMachineMeta.Transitions.Pay.class, value = { States.PartialPaid.class,                    InvoiceStateMachineMeta.States.PaidOff.class }) })            static interface Posted {}            @Function(transition = InvoiceStateMachineMeta.Transitions.Pay.class, value = { States.PartialPaid.class,                    InvoiceStateMachineMeta.States.PaidOff.class })            static interface PartialPaid {}            @End            static interface PaidOff {}        }        @TransitionSet        static interface Transitions {            static interface Post {}            @Conditional(condition = Payable.class, judger = PayableJudger.class, postEval = true)            static interface Pay {}        }        @ConditionSet        static interface Conditions {            static interface Payable {                BigDecimal getTotalAmount();                BigDecimal getPayedAmount();            }        }        public static class Utilities {            public static class PayableJudger implements ConditionalTransition<Payable> {                @Override                public Class<?> doConditionJudge(Payable t) {                    if ( 0 < t.getPayedAmount().compareTo(BigDecimal.ZERO) && 0 < t.getTotalAmount().compareTo(t.getPayedAmount()) ) {                        return PartialPaid.class;                    } else if ( 0 >= t.getTotalAmount().compareTo(t.getPayedAmount()) ) {                        return PaidOff.class;                    } else {                        throw new IllegalStateException();                    }                }            }        }    }    @StateMachine    public static interface InvoiceItemStateMachineMeta {        @StateSet        static interface States {            @Initial            @Function(transition = InvoiceItemStateMachineMeta.Transitions.Pay.class, value = { InvoiceItemStateMachineMeta.States.Paid.class })            static interface Unpaid {}            @End            @InboundWhile(on = { InvoiceStateMachineMeta.States.Posted.class, InvoiceStateMachineMeta.States.PartialPaid.class },                    relation = InvoiceItemStateMachineMeta.Relations.ParentInvoice.class)            static interface Paid {}        }        @TransitionSet        static interface Transitions {            static interface Pay {}        }        @RelationSet        static interface Relations {            @RelateTo(InvoiceStateMachineMeta.class)            static interface ParentInvoice {}        }    }

?

@LifecycleMeta(InvoiceStateMachineMeta.class)    public static class Invoice extends ReactiveObject implements InvoiceStateMachineMeta.Conditions.Payable {        private final BigDecimal totalAmount;;        private BigDecimal payedAmount = new BigDecimal(0D);        private final List<InvoiceItem> items = new ArrayList<>();        public Invoice(final BigDecimal totalAmount) {            initialState(InvoiceStateMachineMeta.States.Draft.class.getSimpleName());            this.totalAmount = totalAmount;        }        @Condition(InvoiceStateMachineMeta.Conditions.Payable.class)        public InvoiceStateMachineMeta.Conditions.Payable getPayable() {            return this;        }        @Override        public BigDecimal getTotalAmount() {            return totalAmount;        }        @Override        public synchronized BigDecimal getPayedAmount() {            return payedAmount;        }        @Transition        public void post() {}        @Transition(InvoiceStateMachineMeta.Transitions.Pay.class)        @PostStateChange(to = InvoiceItemStateMachineMeta.States.Paid.class, observableName = "items", mappedBy = "parent")        public synchronized void onItemPaied(LifecycleContext<InvoiceItem, String> context) {            payedAmount = payedAmount.add(context.getTarget().getPayedAmount());        }        public void addItem(InvoiceItem invoiceItem) {            if ( !items.contains(invoiceItem) ) {                items.add(invoiceItem);            }        }        public List<InvoiceItem> getItems() {            return Collections.unmodifiableList(items);        }    }    @LifecycleMeta(InvoiceItemStateMachineMeta.class)    public static class InvoiceItem extends ReactiveObject {        private int seq;        private BigDecimal amount;        private BigDecimal payedAmount;        private final Invoice parent;        public InvoiceItem(Invoice parent, BigDecimal amount) {            initialState(InvoiceItemStateMachineMeta.States.Unpaid.class.getSimpleName());            this.amount = amount;            this.parent = parent;            this.seq = this.parent.getItems().size() + 1;            this.parent.addItem(this);        }        @Transition        public void pay(final BigDecimal amount) {            if ( 0 < this.amount.compareTo(amount) ) {                throw new IllegalArgumentException("paying amount is not enough to pay this item.");            }            this.payedAmount = amount;        }        public BigDecimal getPayedAmount() {            return payedAmount;        }        @Relation(InvoiceItemStateMachineMeta.Relations.ParentInvoice.class)        public Invoice getParent() {            return this.parent;        }        @Override        public int hashCode() {            final int prime = 31;            int result = 1;            result = prime * result + ( ( parent == null ) ? 0 : parent.hashCode() );            result = prime * result + seq;            return result;        }        @Override        public boolean equals(Object obj) {            if ( this == obj ) return true;            if ( obj == null ) return false;            if ( getClass() != obj.getClass() ) return false;            InvoiceItem other = (InvoiceItem) obj;            if ( parent == null ) {                if ( other.parent != null ) return false;            } else if ( !parent.equals(other.parent) ) return false;            if ( seq != other.seq ) return false;            return true;        }    }

?

    @Test    public void test_relational_callback_post_state_change() {        final Invoice invoice = new Invoice(new BigDecimal(10000.0D));        final InvoiceItem itemOne = new InvoiceItem(invoice, new BigDecimal(4000.0D));        final InvoiceItem itemTwo = new InvoiceItem(invoice, new BigDecimal(4000.0D));        final InvoiceItem itemThree = new InvoiceItem(invoice, new BigDecimal(2000.0D));        invoice.post();        assertState(InvoiceStateMachineMeta.States.Posted.class, invoice);        assertState(InvoiceItemStateMachineMeta.States.Unpaid.class, itemOne);        itemOne.pay(new BigDecimal(4000.0D));        assertState(InvoiceItemStateMachineMeta.States.Paid.class, itemOne);        assertState(InvoiceStateMachineMeta.States.PartialPaid.class, invoice);        itemTwo.pay(new BigDecimal(4000.0D));        assertState(InvoiceItemStateMachineMeta.States.Paid.class, itemTwo);        assertState(InvoiceStateMachineMeta.States.PartialPaid.class, invoice);        itemThree.pay(new BigDecimal(2000.0D));        assertState(InvoiceItemStateMachineMeta.States.Paid.class, itemThree);        assertState(InvoiceStateMachineMeta.States.PaidOff.class, invoice);    }

?前文:生命周期组件框架——关系型状态及服务

热点排行