001    package data.stdforms.singletableformsheet;
002    
003    import sale.*;
004    import sale.stdforms.*;
005    
006    import data.*;
007    import data.stdforms.SingleTableFormSheet;
008    
009    import users.*;
010    
011    /**
012     * A strategy that can be attached to the {@link SingleTableFormSheet#addAddButton "Add" button} of
013     * a {@link SingleTableFormSheet} that displays a {@link Catalog Catalog's} contents.
014     *
015     * <p>This strategy is <i>abstract</i> since the creation of the {@link CatalogItem} is application specific.
016     * It must be defined by overriding {@link #createCatalogItem}.</p>
017     *
018     * @author Steffen Zschaler
019     * @version 2.0 20/08/1999
020     * @since v2.0
021     */
022    public abstract class AbstractAddCatalogItemStrategy extends EditButtonStrategy {
023    
024        /**
025         * The resource bundle key of the label to be shown in the "Define Key" FormSheet.
026         */
027        public static final String KEY_LABEL = "singletableformsheet.abstractaddcatalogitemstrategy.key_label";
028    
029        /**
030         * The Catalog to be edited.
031         *
032         * @serial
033         */
034        protected Catalog m_cCatalog;
035    
036        /**
037         * Create a new AbstractAddCatalogItemStrategy.
038         *
039         * @param c the Catalog to be edited. Must be the same that is displayed in the {@link SingleTableFormSheet}.
040         */
041        public AbstractAddCatalogItemStrategy(Catalog c) {
042            super();
043    
044            m_cCatalog = c;
045        }
046    
047        /**
048         * @override Never
049         */
050        public Transition getEditProcess(SingleTableFormSheet stfs, SaleProcess p, SalesPoint sp) {
051            return new GateChangeTransition(getCreateCIGate(stfs));
052        }
053    
054        /**
055         * Get the first Gate in the sub-process. This Gate asks the user for the key of the new item, creates it in
056         * a new Transition and after editing the new item adds it to the Catalog.
057         *
058         * @override Never Instead, override {@link #getNewKey}, {@link #createCatalogItem}, {@link #getEditCIGate}
059         * and/or {@link #addToCatalog}.
060         *
061         * @param stfs the FormSheet that triggered the sub-process.
062         */
063        protected Gate getCreateCIGate(final SingleTableFormSheet stfs) {
064            return new Gate() {
065                public Transition getNextTransition(SaleProcess p, User u) throws InterruptedException {
066                    final String sKey = getNewKey(stfs, p);
067    
068                    if (sKey != null) {
069                        return new Transition() {
070                            public Gate perform(SaleProcess _p, User _u) {
071                                // create the CatalogItem
072                                final CatalogItem ci = createCatalogItem(sKey);
073    
074                                return getEditCIGate(ci, stfs, new Transition() {
075                                    public Gate perform(SaleProcess __p, User __u) {
076                                        addToCatalog(__p, ci);
077    
078                                        return stfs.getGate();
079                                    }
080                                });
081                            }
082                        };
083                    } else {
084                        return new GateChangeTransition(stfs.getGate());
085                    }
086                }
087            };
088        }
089    
090        /**
091         * Get the key of the new item. Can assume that at a Gate.
092         *
093         * @override Sometimes The default implementation pops up a FormSheet where the user can enter a new
094         * key.
095         *
096         * @param stfs the FormSheet that triggered the sub-process.
097         * @param p the process into which the sub-process was embedded.
098         */
099        protected String getNewKey(SingleTableFormSheet stfs, SaleProcess p) throws InterruptedException {
100            TextInputForm fs = new TextInputForm(stfs.getCaption(), getResourceString(KEY_LABEL), "");
101    
102            p.getContext().popUpFormSheet(p, fs);
103    
104            return ((fs.isCancelled()) ? (null) : (fs.getText()));
105        }
106    
107        /**
108         * Create a new CatalogItem of the given key.
109         *
110         * @override Always The contents of this method is application specific.
111         *
112         * @param sKey the key for which to create a new CatalogItem.
113         *
114         * @return the new CatalogItem.
115         */
116        protected abstract CatalogItem createCatalogItem(String sKey);
117    
118        /**
119         * Get a Gate at which a newly created CatalogItem can be edited by the user.
120         *
121         * @param ci the CatalogItem to be edited.
122         * @param stfs the FormSheet that triggered the sub-process. A transition to this FormSheet's gate must be
123         * leaving the Gate if the user cancels the operation.
124         * @param tOk the Transition that must be leaving the Gate if the user finished editing and did not cancel
125         * the operation or enter invalid data.
126         *
127         * @override Sometimes The default implementation simply continues with <code>tOk</code>.
128         */
129        protected Gate getEditCIGate(CatalogItem ci, SingleTableFormSheet stfs, final Transition tOk) {
130            return new Gate() {
131                public Transition getNextTransition(SaleProcess p, User u) {
132                    return tOk;
133                }
134            };
135        }
136    
137        /**
138         * Add the specified CatalogItem to the Catalog.
139         *
140         * <p>Any error condition should be passed on to {@link FormSheetStrategy#error} in
141         * {@link FormSheetStrategy}.</p>
142         *
143         * @param p the process into which the sub-process was embedded.
144         * @param ci the CatalogItem to be added to the Catalog.
145         *
146         * @override Never
147         */
148        protected void addToCatalog(SaleProcess p, CatalogItem ci) {
149            try {
150                m_cCatalog.add(ci, p.getBasket());
151            }
152            catch (DuplicateKeyException dke) {
153                error(p, DUPLICATE_KEY_EXCEPTION);
154            }
155            catch (DataBasketConflictException dbce) {
156                error(p, DATABASKET_CONFLICT_ERROR);
157            }
158        }
159    
160        /**
161         * Get the resource String for the specified key.
162         *
163         * @override Sometimes The default implementation returns
164         * ""Please specify the CatalogItem's key:"" if asked for {@link #KEY_LABEL}.
165         */
166        protected String getResourceString(String sKey) {
167            if (sKey.equals(KEY_LABEL)) {
168                return "Please specify the CatalogItem's key:";
169            } else {
170                return "[" + sKey + " not defined!]";
171            }
172        }
173    }