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<CatalogItem> 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<CatalogItem> 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 private static final long serialVersionUID = -2998880870091731985L;
066
067 public Transition getNextTransition(SaleProcess p, User u) throws InterruptedException {
068 final String sKey = getNewKey(stfs, p);
069
070 if (sKey != null) {
071 return new Transition() {
072 private static final long serialVersionUID = 5776239284990662515L;
073
074 public Gate perform(SaleProcess _p, User _u) {
075 // create the CatalogItem
076 final CatalogItem ci = createCatalogItem(sKey);
077
078 return getEditCIGate(ci, stfs, new Transition() {
079 private static final long serialVersionUID = 3410018301525560100L;
080
081 public Gate perform(SaleProcess __p, User __u) {
082 addToCatalog(__p, ci);
083
084 return stfs.getGate();
085 }
086 });
087 }
088 };
089 } else {
090 return new GateChangeTransition(stfs.getGate());
091 }
092 }
093 };
094 }
095
096 /**
097 * Get the key of the new item. Can assume that at a Gate.
098 *
099 * @override Sometimes The default implementation pops up a FormSheet where the user can enter a new
100 * key.
101 *
102 * @param stfs the FormSheet that triggered the sub-process.
103 * @param p the process into which the sub-process was embedded.
104 */
105 protected String getNewKey(SingleTableFormSheet stfs, SaleProcess p) throws InterruptedException {
106 TextInputForm fs = new TextInputForm(stfs.getCaption(), getResourceString(KEY_LABEL), "");
107
108 p.getContext().popUpFormSheet(p, fs);
109
110 return ((fs.isCancelled()) ? (null) : (fs.getText()));
111 }
112
113 /**
114 * Create a new CatalogItem of the given key.
115 *
116 * @override Always The contents of this method is application specific.
117 *
118 * @param sKey the key for which to create a new CatalogItem.
119 *
120 * @return the new CatalogItem.
121 */
122 protected abstract CatalogItem createCatalogItem(String sKey);
123
124 /**
125 * Get a Gate at which a newly created CatalogItem can be edited by the user.
126 *
127 * @param ci the CatalogItem to be edited.
128 * @param stfs the FormSheet that triggered the sub-process. A transition to this FormSheet's gate must be
129 * leaving the Gate if the user cancels the operation.
130 * @param tOk the Transition that must be leaving the Gate if the user finished editing and did not cancel
131 * the operation or enter invalid data.
132 *
133 * @override Sometimes The default implementation simply continues with <code>tOk</code>.
134 */
135 protected Gate getEditCIGate(CatalogItem ci, SingleTableFormSheet stfs, final Transition tOk) {
136 return new Gate() {
137 private static final long serialVersionUID = -5294897398632733547L;
138
139 public Transition getNextTransition(SaleProcess p, User u) {
140 return tOk;
141 }
142 };
143 }
144
145 /**
146 * Add the specified CatalogItem to the Catalog.
147 *
148 * <p>Any error condition should be passed on to {@link FormSheetStrategy#error} in
149 * {@link FormSheetStrategy}.</p>
150 *
151 * @param p the process into which the sub-process was embedded.
152 * @param ci the CatalogItem to be added to the Catalog.
153 *
154 * @override Never
155 */
156 protected void addToCatalog(SaleProcess p, CatalogItem ci) {
157 try {
158 m_cCatalog.add(ci, p.getBasket());
159 }
160 catch (DuplicateKeyException dke) {
161 error(p, DUPLICATE_KEY_EXCEPTION);
162 }
163 catch (DataBasketConflictException dbce) {
164 error(p, DATABASKET_CONFLICT_ERROR);
165 }
166 }
167
168 /**
169 * Get the resource String for the specified key.
170 *
171 * @override Sometimes The default implementation returns
172 * ""Please specify the CatalogItem's key:"" if asked for {@link #KEY_LABEL}.
173 */
174 protected String getResourceString(String sKey) {
175 if (sKey.equals(KEY_LABEL)) {
176 return "Please specify the CatalogItem's key:";
177 } else {
178 return "[" + sKey + " not defined!]";
179 }
180 }
181 }