001: package simpleorm.simplewebapp.core;
002:
003: import simpleorm.simplewebapp.core.WButton;
004: import simpleorm.simplewebapp.core.WField;
005: import simpleorm.simplewebapp.core.WPage;
006: import simpleorm.simplewebapp.core.WPageEvents;
007: import simpleorm.simplewebapp.ute.WDummyMap;
008: import simpleorm.simplewebapp.context.WPageContext;
009: import simpleorm.simplewebapp.core.WMenuItemGlobal;
010:
011: import java.util.*;
012:
013: /**
014: * A page is composed of multiple pagelets that represent things like a Tree or a Crud section.
015: * So a Tree/Crud page consists of two pagelets.<p>
016: *
017: * Simple HTML really works one page at a time, so pagelets are kept simple.
018: * For example, the namespaces of their fields overlaps to be simple HTML field names.
019: * If you are trying to do something too clever with pagelets try just using multiple pages.<p>
020: *
021: * See WPageEvents for details of how the events are fired and grouped together.
022: */
023: public class WPagelet extends WPageEvents {
024:
025: WPage wPage;
026: /** Name of the pagelet, eg. "list" or "crud".
027: * Used by tag libraries such as esgp:autoCrud to identify the correct the correct pagelet.
028: * (Not the name of the page itself, eg. WCustomerPage.)
029: */
030:
031: String name;
032:
033: LinkedHashMap<String, WFieldGroup> fieldGroups = new LinkedHashMap(
034: 4); // key is shortName
035:
036: /** List of all fields in all groups, handy short cut. */
037: LinkedHashMap<String, WField> allFields = new LinkedHashMap(20); // key is shortName
038:
039: /**
040: * This weird structure is needed so that JSPs will return
041: * errors for ${wPage.fields.myFieldOopsxyz}
042: * (Jsps will only access a Map, not a method with a parameter.)
043: */
044: Map<String, WField> allFieldsStrict = new WDummyMap() {
045: public Object get(Object key) {
046: Object val = allFields.get(key);
047: if (val == null)
048: throw new RuntimeException("No Field named " + key
049: + " in " + this );
050: return val;
051: }
052: };
053:
054: /**
055: * Where to redirect to if our form was successfully processed.
056: * (Normally the List form that called the Crud form.)
057: * See WPage.actualRedirectUrl.
058: */
059: String potentialSuccessUrl;
060:
061: public <G extends WFieldGroup> G addGroup(WPagelet pagelet, G group) {
062: group.setPagelet(pagelet, wPage);
063: fieldGroups.put(group.getName(), group);
064: return group;
065: }
066:
067: /**
068: * Adds field to the group AND the entire page.
069: */
070: public <F extends WField> F addField(WFieldGroup group, F field) {
071: field.setPagelet(group.pagelet, wPage);
072: allFields.put(field.getName(), field);
073: if (field.group != null)
074: throw new WException("Field already has a group " + field
075: + field.group);
076: field.group = group;
077: group.add(field);
078: return field;
079: }
080:
081: /**
082: * Returns field named name, exception if not found.
083: * Can be useful for generated fields, but normally just use
084: * WField variables instead.
085: */
086: public WField getFieldStrict(String shortName) {
087: WField field = (WField) allFields.get(shortName);
088: if (field == null)
089: throw new WException("No Field named " + shortName);
090: return field;
091: }
092:
093: /**
094: * Returns field group, exception if not found.
095: */
096: public WFieldGroup getFieldGroup(String groupName) {
097: WFieldGroup g = fieldGroups.get(groupName);
098: if (g == null)
099: throw new WException("No group " + groupName + this );
100: return g;
101: }
102:
103: /**
104: * This must be a one step method to work arround bugs in JSP/EL
105: */
106: public Collection<WFieldGroup> getFieldGroupsValues() {
107: return fieldGroups.values();
108: }
109:
110: /**
111: * Get map of all fields.
112: * get(key) on that map returns null if key not found, as normal.
113: * cf.getAllFieldsStrict.
114: */
115: public @Deprecated
116: Map<String, WField> getAllFieldsNull() {
117: return Collections.unmodifiableMap(allFields);
118: }
119:
120: /**
121: * The collection of fields; (strictness irrelevant).
122: */
123: public Collection<WField> getAllFieldValues() {
124: return allFields.values();
125: }
126:
127: // todo add WPageletGroups
128:
129: /**
130: * Registers itself with page.
131: * Note that this MUST be in the constructor, not a separate
132: * register() method, so that things like buttons can be conveniently added
133: * to the page in constructors.
134: */
135: public WPagelet(WPage wpage, String name) {
136: this .wPage = wpage;
137: this .name = name;
138: wPage.getPageStructure().pagelets.put(name, this );
139: }
140:
141: public WButton getSubmitButton() {
142: return wPage.getSubmitButton();
143: }
144:
145: /**
146: * True if the form has been submitted, and thus should be validated and then redirected etc.
147: */
148: public boolean wasSubmitted() {
149: WButton sub = getPage().getSubmitButton();
150: return sub != null && sub.pagelet == this ;
151: }
152:
153: /** Indicates that an unhandled WValidationException was thrown by this pageLET.
154: * Mainly used in onWasMaybeErroreous overrides. */
155: public boolean isErroneous() {
156: for (WValidationException ve : getPage().getErrors())
157: if (ve.getPagelet() == this )
158: return true;
159: return false;
160: }
161:
162: /**
163: * Nulls all fields on this pagelet.
164: * Called after successful crud submit.
165: * Needed for ListPage where we don't actually
166: * redirect.
167: */
168: public void nullAllFields() {
169: for (WField fld : getAllFieldValues()) {
170: fld.setValue(null);
171: }
172: }
173:
174: /**
175: * Does <getProperties property="*"/> into crudFields
176: * (Regardless of wheter the form wasSubmitted -- gets and posts.)
177: * Determines non-submit referer.
178: */
179: protected void retrieveParameters() {
180: WPageContext pageContext = getPage().getPageContext();
181: String bname = pageContext.getParameter(WButton.BUTTONS_NAME);
182: getPage().setSubmitButton(
183: getPage().getButtonBar().findButton(bname)); // todo buttons are weird
184: if (logger().isDebug())
185: logger().debug(
186: "-- Parameters: Submit Button: "
187: + getSubmitButton());
188: for (WField field : getAllFieldValues()) {
189: if (!field.notRetrieved) {
190: String par = pageContext.getParameter(field
191: .getHtmlName());
192: field.setPostedText(par);
193: if (logger().isDebug())
194: logger().debug(
195: " " + field.getName() + " = "
196: + field.getText());
197: }
198: }
199: determineSuccessUrl();
200: }
201:
202: /**
203: * Calls validators, building up errors List.
204: * Multiple errors are supported, but only one per field.
205: */
206: void validateFields() throws Exception {
207: for (WField field : getAllFieldValues()) {
208: try {
209: field.validateField();
210: } catch (WValidationException ve) {
211: ve.setPagelet(this );
212: getPage().getErrors().add(ve);
213: }
214: }
215: }
216:
217: void determineSuccessUrl() {
218: // if (! wasSubmitted() ) {
219: // //todo referUrl = getPage().getPageContext().getRefererUrl();
220: // // Need to keep this over post submissions. ViewState.
221: // }
222: WMenuItemGlobal myItem = getPage().getPageItem();
223: if (myItem != null) { // null during tests
224: WMenuItemGlobal successItem = myItem.getSuccessItem();
225: if (successItem != null)
226: potentialSuccessUrl = successItem
227: .getAbsoluteUrl(getPage());
228: }
229: }
230:
231: public WButton addNewButton(String nameValue) {
232: return wPage.getPageStructure().addNewButton(nameValue,
233: (WPagelet) this );
234: }
235:
236: void onFinalizeInternal() throws Exception {
237: fieldGroups = null;
238: allFields = null;
239: }
240:
241: public String toString() {
242: return "{WPagelet " + name + "}";
243: }
244:
245: public WLog logger() {
246: return wPage.logger;
247: }
248:
249: /** Convenience logger().debug() method.
250: * Be sure to use if loger().isDebug guards for anything effecient sensitive. */
251: public void debug(String msg) {
252: logger().debug(msg);
253: };
254:
255: public WPageStructure getPageStructure() {
256: return getPage().getPageStructure();
257: }
258:
259: /////////////// Generated /////////////////////
260: public String getName() {
261: return name;
262: }
263:
264: public Map<String, WFieldGroup> getFieldGroups() {
265: return Collections.unmodifiableMap(fieldGroups);
266: }
267:
268: public Map<String, WField> getAllFieldsStrict() {
269: return allFieldsStrict;
270: }
271:
272: public WPage getPage() {
273: return wPage;
274: }
275:
276: public String getPotentialSuccessUrl() {
277: return potentialSuccessUrl;
278: }
279:
280: public void setPotentialSuccessUrl(String potentialSuccessUrl) {
281: this.potentialSuccessUrl = potentialSuccessUrl;
282: }
283: }
|