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 }