001: // THIS SOFTWARE IS PROVIDED BY SOFTARIS PTY.LTD. AND OTHER METABOSS
002: // CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
003: // BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
004: // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTARIS PTY.LTD.
005: // OR OTHER METABOSS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
006: // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
007: // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
008: // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
009: // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
010: // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
011: // EVEN IF SOFTARIS PTY.LTD. OR OTHER METABOSS CONTRIBUTORS ARE ADVISED OF THE
012: // POSSIBILITY OF SUCH DAMAGE.
013: //
014: // Copyright 2000-2005 © Softaris Pty.Ltd. All Rights Reserved.
015: package com.metaboss.enterprise.xi.enhydrabarracuda;
016:
017: import java.lang.reflect.Field;
018: import java.lang.reflect.Method;
019: import java.util.HashMap;
020: import java.util.HashSet;
021: import java.util.Iterator;
022: import java.util.Set;
023:
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.enhydra.xml.xmlc.StreamXMLCLogger;
027: import org.enhydra.xml.xmlc.XMLCFactory;
028: import org.enhydra.xml.xmlc.XMLCStdFactory;
029: import org.w3c.dom.NodeList;
030: import org.w3c.dom.html.HTMLAnchorElement;
031: import org.w3c.dom.html.HTMLCollection;
032: import org.w3c.dom.html.HTMLDocument;
033: import org.w3c.dom.html.HTMLElement;
034: import org.w3c.dom.html.HTMLFormElement;
035:
036: import com.metaboss.enterprise.ui.UIException;
037: import com.metaboss.enterprise.ui.UIInputValidationException;
038: import com.metaboss.enterprise.ui.UIUnexpectedProgramConditionException;
039: import com.metaboss.util.ReflectionUtils;
040:
041: /** This class represents a page of the web application
042: * Each instance of the page is a single html document rendered as the result of
043: * particular navigation move. Page owns some controls
044: * some forms (which in turn own some controls too). */
045: public abstract class Page {
046: // Static logging instance
047: private static final Log sLogger = LogFactory.getLog(Page.class);
048:
049: // This factory is used to load XMLC resource classes
050: private static XMLCFactory sXMLCFactory = new XMLCStdFactory(
051: Page.class.getClassLoader(), new StreamXMLCLogger());
052:
053: // The metadata we keep per widget type.
054: // Note that this approach is here more for the future where
055: // some kind of widget type metadata may need to be kept
056: private static class WidgetMetadata {
057: // The class, which represents this widget
058: public Class mClass = null;
059: }
060:
061: // The metadata we keep per widget per page
062: private static class PageWidgetMetadata {
063: // Resource id of the form this element belongs to. can be null for the elements
064: // which are sitting directly on the page
065: public String mFormResourceId = null;
066: // Resource id of the element
067: public String mWidgetResourceId = null;
068: public WidgetMetadata mWidgetMetadata = null;
069: public Method mHTMLElementGetterMethod = null;
070: }
071:
072: // The metadata we keep per form per page
073: private static class PageFormMetadata {
074: // Resource id of the form
075: public String mFormResourceId = null;
076: // The action class to invoke when form is actioned
077: public Class mActionClass = null;
078: // Names of all submit imputs which can cause form submit to occur
079: public Set mSubmitControlNames = new HashSet();
080: }
081:
082: // The metadata we keep per page
083: private static class PageMetadata {
084: public String mPageId = null;
085: public String mPageUrl = null;
086: public Class mPageClass = null;
087: public Class mDocumentClass = null;
088: // Widget metadata indexed by widget resource id on the page
089: public HashMap mWidgetMetadataRepository = new HashMap(0);
090: // Form metadata indexed by form resource id on the page
091: public HashMap mFormMetadataRepository = new HashMap(0);
092: }
093:
094: // The Metadata indexed by Page Id
095: // Note that this relationship will only be established when HTML first created
096: private static HashMap sPageIdMap = new HashMap(0);
097: // The Metadata indexed by Widget class
098: // Note that this relationship may only be established when first widget with this class is bound
099: private static HashMap sWidgetClassMap = new HashMap(0);
100: // The Metadata indexed by Document class
101: // Note that this relationship may only be established when HTML first created
102: private static HashMap sDocumentClassMap = new HashMap(0);
103:
104: /** Binds document to this page. */
105: public static void bindDocument(Class pDocumentClass,
106: Class pPageClass) {
107: // Check that the page class is of the right type
108: if (!ReflectionUtils.isSubtype(pPageClass, Page.class))
109: throw new IllegalArgumentException("Class "
110: + pPageClass.getName() + " is not a subclass of "
111: + Page.class.getName());
112: // Check that the document class is of the right type
113: if (!ReflectionUtils.isSubtype(pDocumentClass,
114: HTMLDocument.class))
115: throw new IllegalArgumentException("Class "
116: + pDocumentClass.getName()
117: + " is not a subclass of "
118: + HTMLDocument.class.getName());
119: // There can only be one document metadata definition at all times
120: if (sDocumentClassMap.containsKey(pDocumentClass))
121: throw new IllegalArgumentException("Document "
122: + pDocumentClass.getName()
123: + " is already bound to the page");
124:
125: // Prepare metadata and store it in all maps
126: PageMetadata lPageMetadata = new PageMetadata();
127: lPageMetadata.mPageId = getPageId(pDocumentClass);
128: lPageMetadata.mPageUrl = getPageUrl(pDocumentClass);
129: lPageMetadata.mPageClass = pPageClass;
130: lPageMetadata.mDocumentClass = pDocumentClass;
131:
132: sPageIdMap.put(lPageMetadata.mPageId, lPageMetadata);
133: sDocumentClassMap.put(lPageMetadata.mDocumentClass,
134: lPageMetadata);
135:
136: // This section below deals with creation of the form metadata
137: HTMLDocument lHTMLDocument = (HTMLDocument) sXMLCFactory
138: .create(pDocumentClass);
139: NodeList lForms = lHTMLDocument.getElementsByTagName("FORM");
140: for (int i = 0; i < lForms.getLength(); i++) {
141: HTMLFormElement lFormElement = (HTMLFormElement) lForms
142: .item(i);
143: String lFormId = lFormElement.getId();
144: if (lFormId != null && lFormId.length() > 0) {
145: // This form has an id, therefore we should collect the metainformation about this form.
146: PageFormMetadata lFormMetadata = new PageFormMetadata();
147: lFormMetadata.mFormResourceId = lFormId;
148: HTMLCollection lControlElements = lFormElement
149: .getElements();
150: for (int j = 0; j < lControlElements.getLength(); j++) {
151: HTMLElement lControlElement = (HTMLElement) lControlElements
152: .item(j);
153: if (lControlElement.getTagName().equalsIgnoreCase(
154: "INPUT")) {
155: String lInputType = lControlElement
156: .getAttribute("type");
157: if (lInputType != null
158: && lInputType
159: .equalsIgnoreCase("SUBMIT"))
160: lFormMetadata.mSubmitControlNames
161: .add(lControlElement
162: .getAttribute("NAME"));
163: }
164: }
165: if (lFormMetadata.mSubmitControlNames.size() == 0)
166: sLogger.warn("Document " + lPageMetadata.mPageUrl
167: + " has a form without submit buttons.");
168:
169: // Add information about this form to the page metadata storage
170: lPageMetadata.mFormMetadataRepository.put(lFormId,
171: lFormMetadata);
172: } else
173: sLogger
174: .warn("Document "
175: + lPageMetadata.mPageUrl
176: + " has a form without an id. This form can not be acessed or used programmatically.");
177: }
178: }
179:
180: /** Binds control to this page */
181: public static void bindFormWidget(Class pDocumentClass,
182: String pFormResourceId, String pWidgetResourceId,
183: Class pWidgetClass) {
184: // Call common implementation
185: bindWidgetHelper(pDocumentClass, pWidgetClass, pFormResourceId,
186: pWidgetResourceId);
187: }
188:
189: /** Binds control to this page */
190: public static void bindWidget(Class pDocumentClass,
191: String pWidgetResourceId, Class pWidgetClass) {
192: // Call common implementation
193: bindWidgetHelper(pDocumentClass, pWidgetClass, null,
194: pWidgetResourceId);
195: }
196:
197: /** Binds action class to the form on this */
198: public static void bindFormAction(Class pDocumentClass,
199: String pFormResourceId, Class pActionClass) {
200: // Check that the document class is of the right type
201: if (!ReflectionUtils.isSubtype(pDocumentClass,
202: HTMLDocument.class))
203: throw new IllegalArgumentException("Class "
204: + pDocumentClass.getName()
205: + " is not a subclass of "
206: + HTMLDocument.class.getName());
207: // Check that the action class is of the right type
208: if (!ReflectionUtils.isSubtype(pActionClass, Action.class))
209: throw new IllegalArgumentException("Class "
210: + pActionClass.getName() + " is not a subclass of "
211: + Action.class.getName());
212:
213: // Get to the page's metadata
214: PageMetadata lPageMetadata = (PageMetadata) sDocumentClassMap
215: .get(pDocumentClass);
216: if (lPageMetadata == null)
217: throw new IllegalArgumentException(
218: "Document "
219: + pDocumentClass.getName()
220: + " is not bound to the page, unable to bind widget");
221: // Expect to get existing page form metadata
222: PageFormMetadata lPageFormMetadata = (PageFormMetadata) lPageMetadata.mFormMetadataRepository
223: .get(pFormResourceId);
224: if (lPageFormMetadata == null)
225: throw new IllegalArgumentException("Form with id "
226: + pFormResourceId
227: + " does not have matching resource in "
228: + pDocumentClass.getName());
229: // Check if this element is already bound to the action
230: if (lPageFormMetadata.mActionClass != null
231: && lPageFormMetadata.mActionClass.equals(pActionClass) == false)
232: throw new IllegalArgumentException("Form with id "
233: + pFormResourceId
234: + " is already bound to the action.");
235: // Assign action to the form
236: lPageFormMetadata.mActionClass = pActionClass;
237: }
238:
239: /** Returns URL of the page with specified Id */
240: public static String getPageUrl(String pPageId) {
241: // Get to the page's metadata
242: PageMetadata lPageMetadata = (PageMetadata) sPageIdMap
243: .get(pPageId);
244: if (lPageMetadata == null)
245: return null;
246: return lPageMetadata.mPageUrl;
247: }
248:
249: /** Returns class of the widget with specified id on specified page */
250: public static Class getWidgetClass(String pPageId, String pWidgetId) {
251: // Get to the page's metadata
252: PageMetadata lPageMetadata = (PageMetadata) sPageIdMap
253: .get(pPageId);
254: if (lPageMetadata == null)
255: return null;
256: PageWidgetMetadata lPageWidgetMetadata = (PageWidgetMetadata) lPageMetadata.mWidgetMetadataRepository
257: .get(pWidgetId);
258: if (lPageWidgetMetadata == null)
259: return null;
260: return lPageWidgetMetadata.mWidgetMetadata.mClass;
261: }
262:
263: /** Returns class of the action bound to the specified form */
264: public static Class getFormActionClass(String pPageId,
265: String pFormId) {
266: // Get to the page's metadata
267: PageMetadata lPageMetadata = (PageMetadata) sPageIdMap
268: .get(pPageId);
269: if (lPageMetadata == null)
270: return null;
271: PageFormMetadata lPageFormMetadata = (PageFormMetadata) lPageMetadata.mFormMetadataRepository
272: .get(pFormId);
273: if (lPageFormMetadata == null)
274: return null;
275: return lPageFormMetadata.mActionClass;
276: }
277:
278: /** Binds control to this page */
279: private static void bindWidgetHelper(Class pDocumentClass,
280: Class pWidgetClass, String pFormResourceId,
281: String pWidgetResourceId) {
282: // Check that the document class is of the right type
283: if (!ReflectionUtils.isSubtype(pDocumentClass,
284: HTMLDocument.class))
285: throw new IllegalArgumentException("Class "
286: + pDocumentClass.getName()
287: + " is not a subclass of "
288: + HTMLDocument.class.getName());
289: // Check that the element class is of the right type
290: if (!ReflectionUtils.isSubtype(pWidgetClass, Widget.class))
291: throw new IllegalArgumentException("Class "
292: + pWidgetClass.getName() + " is not a subclass of "
293: + Widget.class.getName());
294: // Get to the widget's metadata
295: WidgetMetadata lWidgetMetadata = (WidgetMetadata) sWidgetClassMap
296: .get(pWidgetClass);
297: if (lWidgetMetadata == null) {
298: lWidgetMetadata = new WidgetMetadata();
299: lWidgetMetadata.mClass = pWidgetClass;
300: sWidgetClassMap
301: .put(lWidgetMetadata.mClass, lWidgetMetadata);
302: }
303:
304: // Get to the page's metadata
305: PageMetadata lPageMetadata = (PageMetadata) sDocumentClassMap
306: .get(pDocumentClass);
307: if (lPageMetadata == null)
308: throw new IllegalArgumentException(
309: "Document "
310: + pDocumentClass.getName()
311: + " is not bound to the page, unable to bind widget");
312: // Check if this element is already registered
313: if (lPageMetadata.mWidgetMetadataRepository
314: .containsKey(pWidgetResourceId))
315: throw new IllegalArgumentException("Resource with id "
316: + pWidgetResourceId
317: + " is already bound to the element on this page.");
318: PageWidgetMetadata lPageWidgetMetadata = new PageWidgetMetadata();
319: lPageWidgetMetadata.mWidgetResourceId = pWidgetResourceId;
320: lPageWidgetMetadata.mFormResourceId = pFormResourceId;
321: lPageWidgetMetadata.mWidgetMetadata = lWidgetMetadata;
322: lPageWidgetMetadata.mHTMLElementGetterMethod = Util
323: .getDocumentElementGettterMethod(pDocumentClass,
324: pWidgetResourceId);
325: if (lPageWidgetMetadata.mHTMLElementGetterMethod == null)
326: throw new RuntimeException("Widget with Id "
327: + pWidgetResourceId
328: + " does not have matching resource in "
329: + pDocumentClass.getName());
330: // Note that the reflection is deferred until latter so servlet can return errors properly
331: lPageMetadata.mWidgetMetadataRepository.put(pWidgetResourceId,
332: lPageWidgetMetadata);
333: }
334:
335: // The metadata describing this page
336: private PageMetadata mPageMetadata = null;
337: // An instance of the HTML document this page represents
338: private HTMLDocument mHTMLDocument = null;
339: // The Application which owns this instance
340: private Application mApplication = null;
341: // Navigation move details
342: private Application.NavigationMove mNavigationMove = null;
343: // The map of bound elements on this page
344: private HashMap mWidgets = null;
345:
346: /** This creator fully creates the instance of the page.
347: * @param pPredescessor optional predescessor page
348: */
349: public static Page createInstance(Class pResourceClass,
350: Application pApplication,
351: Application.NavigationMove pNavigationMove)
352: throws IllegalAccessException, InstantiationException,
353: UIException {
354: PageMetadata lPageMetadata = (PageMetadata) sDocumentClassMap
355: .get(pResourceClass);
356: if (lPageMetadata == null) {
357: // Try to load application class now
358: // Loading of the application class will do all the binding necessary
359: String lResourceClassName = pResourceClass.getName();
360: String lApplicationClassName = lResourceClassName
361: .substring(0, lResourceClassName.length() - 4);
362: try {
363: Class lApplicationClass = Class
364: .forName(lApplicationClassName);
365: } catch (ClassNotFoundException e) {
366: // Ignore - will install dynamic page
367: } catch (NoClassDefFoundError e) {
368: // Ignore - will install dynamic page
369: }
370:
371: // Check if binding is established now
372: if ((lPageMetadata = (PageMetadata) sDocumentClassMap
373: .get(pResourceClass)) == null) {
374: // Still no luck - bind to default
375: // Bind this page to the default page implementation
376: sLogger
377: .warn("Document "
378: + pResourceClass
379: + " does not have specialised page class associated with it. Will use default");
380: bindDocument(pResourceClass, GenericPage.class);
381: lPageMetadata = (PageMetadata) sDocumentClassMap
382: .get(pResourceClass);
383: }
384: }
385: // By now we have got fully initialised metadata
386: Page lInstance = (Page) lPageMetadata.mPageClass.newInstance();
387: // Set up all member variables
388: lInstance.mNavigationMove = pNavigationMove;
389: lInstance.mApplication = pApplication;
390: lInstance.mHTMLDocument = (HTMLDocument) sXMLCFactory
391: .create(pResourceClass);
392: lInstance.mPageMetadata = lPageMetadata;
393: // If this page has been bound - create instances of the elements
394: if (lInstance.mPageMetadata != null) {
395: // We have found page metadata - we need to iterate through elements and instantiate them
396: lInstance.mWidgets = new HashMap();
397: Iterator lWidgetMetadataIterator = lInstance.mPageMetadata.mWidgetMetadataRepository
398: .values().iterator();
399: while (lWidgetMetadataIterator.hasNext()) {
400: PageWidgetMetadata lPageWidgetMetadata = (PageWidgetMetadata) lWidgetMetadataIterator
401: .next();
402: // Instantiate widget
403: Widget lWidget = Widget.createInstance(lInstance,
404: lPageWidgetMetadata.mWidgetMetadata.mClass,
405: lPageWidgetMetadata.mFormResourceId,
406: lPageWidgetMetadata.mWidgetResourceId);
407: // Store widget itself on the page
408: lInstance.mWidgets.put(
409: lPageWidgetMetadata.mWidgetResourceId, lWidget);
410: // Instantiate widget model
411: WidgetModel lWidgetModel = lWidget.createModel();
412: // Store model in the context
413: if (lPageWidgetMetadata.mFormResourceId != null)
414: lInstance.mNavigationMove.putFormWidgetModel(
415: lInstance.mPageMetadata.mPageId,
416: lPageWidgetMetadata.mFormResourceId,
417: lPageWidgetMetadata.mWidgetResourceId,
418: lWidgetModel);
419: else
420: lInstance.mNavigationMove.putWidgetModel(
421: lInstance.mPageMetadata.mPageId,
422: lPageWidgetMetadata.mWidgetResourceId,
423: lWidgetModel);
424: }
425: }
426: // Last, but not least initialise the page
427: lInstance.initialise();
428: // Returns the instance for further processing
429: return lInstance;
430: }
431:
432: /** Returns the HTML Element this control is bound to */
433: HTMLElement getBoundDocumentElement(String pWidgetResourceId) {
434: try {
435: PageWidgetMetadata lWidgetMetadata = (PageWidgetMetadata) mPageMetadata.mWidgetMetadataRepository
436: .get(pWidgetResourceId);
437: if (lWidgetMetadata == null
438: || lWidgetMetadata.mHTMLElementGetterMethod == null)
439: return null;
440: return (HTMLElement) lWidgetMetadata.mHTMLElementGetterMethod
441: .invoke(mHTMLDocument, null);
442: } catch (java.lang.reflect.InvocationTargetException e) {
443: throw new RuntimeException("Caught unexpected exception : "
444: + e.getTargetException().getMessage());
445: } catch (java.lang.IllegalAccessException e) {
446: throw new RuntimeException("Caught unexpected exception : "
447: + e.getMessage());
448: }
449: }
450:
451: /** @return Model for the requested widget or null if nothing found */
452: public WidgetModel getWidgetModel(String pWidgetResourceId) {
453: // Find out if this is a form widget - this means that we need to check forms storage first
454: PageWidgetMetadata lWidgetMetadata = (PageWidgetMetadata) mPageMetadata.mWidgetMetadataRepository
455: .get(pWidgetResourceId);
456: if (lWidgetMetadata != null
457: && lWidgetMetadata.mFormResourceId != null)
458: return mNavigationMove.getFormWidgetModel(
459: mPageMetadata.mPageId,
460: lWidgetMetadata.mFormResourceId, pWidgetResourceId);
461: return mNavigationMove.getWidgetModel(mPageMetadata.mPageId,
462: pWidgetResourceId);
463: }
464:
465: /** Stores the widget values for the particular widget */
466: public void putWidgetModel(String pWidgetResourceId,
467: WidgetModel pWidgetModel) {
468: // Find out if this is a form widget - this means that we need to check forms storage first
469: PageWidgetMetadata lWidgetMetadata = (PageWidgetMetadata) mPageMetadata.mWidgetMetadataRepository
470: .get(pWidgetResourceId);
471: if (lWidgetMetadata != null
472: && lWidgetMetadata.mFormResourceId != null)
473: mNavigationMove.putFormWidgetModel(mPageMetadata.mPageId,
474: lWidgetMetadata.mFormResourceId, pWidgetResourceId,
475: pWidgetModel);
476: else
477: mNavigationMove.putWidgetModel(mPageMetadata.mPageId,
478: pWidgetResourceId, pWidgetModel);
479: }
480:
481: /** Retrieves HTMLDocument in its current form */
482: public HTMLDocument getHTMLDocument() {
483: return mHTMLDocument;
484: }
485:
486: /** Getter for the application */
487: public Application getApplication() {
488: return mApplication;
489: }
490:
491: /** Returns the value of a navigation parameter as a String, or throws exception if the specified parameter does not exist. */
492: public String getMandatoryParameter(String pParameterName)
493: throws UIInputValidationException,
494: UIUnexpectedProgramConditionException {
495: return mNavigationMove.getMandatoryParameter(pParameterName);
496: }
497:
498: /** Returns the value of a navigation parameter as a String, or specified default value if the parameter does not exist. */
499: public String getParameter(String pParameterName,
500: String pDefaultValue)
501: throws UIUnexpectedProgramConditionException {
502: return mNavigationMove.getParameter(pParameterName,
503: pDefaultValue);
504: }
505:
506: /** This lifecycle method is expected to initialise the page.
507: * This mostly means setting up controls and making some service calls */
508: public void initialise() throws UIException {
509: // Nothing to do by default
510: }
511:
512: /** This lifecycle method is expected to render dynamic parts of the page */
513: public void render() throws UIUnexpectedProgramConditionException {
514: // Insert looping through controls and rendering them in here
515: if (mWidgets != null) {
516: Iterator lWidgetsIterator = mWidgets.values().iterator();
517: while (lWidgetsIterator.hasNext()) {
518: Widget lWidget = (Widget) lWidgetsIterator.next();
519: lWidget.render();
520: }
521: }
522: }
523:
524: /** Iterates through all anchors and forms, finds the ones which look like belonging to the application
525: * and signs them. Signing means making sure that all system parameters are present */
526: public void signAnchors() {
527: // Deal with anchors
528: org.w3c.dom.NodeList lAnchorList = mHTMLDocument
529: .getElementsByTagName("A");
530: int lAnchorsCount = lAnchorList.getLength();
531: for (int i = 0; i < lAnchorsCount; i++) {
532: HTMLAnchorElement lAnchor = (HTMLAnchorElement) lAnchorList
533: .item(i);
534: String lHref = lAnchor.getHref();
535: if (mApplication.isOwnedUrl(lHref)) {
536: // This URL is owned by our application. Sign it.
537: lHref = Util.setURLParameter(lHref,
538: Constants.PAGE_ID_REQUEST_PARAMETER_NAME,
539: mPageMetadata.mPageId);
540: lHref = Util
541: .setURLParameter(
542: lHref,
543: Constants.NAVIGATION_INSTANCE_REQUEST_PARAMETER_NAME,
544: mNavigationMove.getInstanceId());
545: // Also supply anchor id if we have one
546: String lAnchorId = lAnchor.getId();
547: if (lAnchorId != null) {
548: lAnchorId = lAnchorId.trim();
549: if (lAnchorId.length() > 0) {
550: lHref = Util
551: .setURLParameter(
552: lHref,
553: Constants.ANCHOR_ID_REQUEST_PARAMETER_NAME,
554: lAnchorId);
555: }
556: }
557: lAnchor.setHref(lHref);
558: }
559: }
560: // Deal with forms
561: org.w3c.dom.NodeList lFormList = mHTMLDocument
562: .getElementsByTagName("FORM");
563: int lFormsCount = lFormList.getLength();
564: for (int i = 0; i < lFormsCount; i++) {
565: HTMLFormElement lForm = (HTMLFormElement) lFormList.item(i);
566: String lAction = lForm.getAction();
567: if (mApplication.isOwnedUrl(lAction)) {
568: // This URL is owned by our application. Sign it with navigation id.
569: lAction = Util.setURLParameter(lAction,
570: Constants.PAGE_ID_REQUEST_PARAMETER_NAME,
571: mPageMetadata.mPageId);
572: lAction = Util
573: .setURLParameter(
574: lAction,
575: Constants.NAVIGATION_INSTANCE_REQUEST_PARAMETER_NAME,
576: mNavigationMove.getInstanceId());
577: // Also supply form id if we have one
578: String lFormId = lForm.getId();
579: if (lFormId != null) {
580: lFormId = lFormId.trim();
581: if (lFormId.length() > 0) {
582: lAction = Util
583: .setURLParameter(
584: lAction,
585: Constants.FORM_ID_REQUEST_PARAMETER_NAME,
586: lFormId);
587: }
588: }
589: // Now save this enriched action
590: lForm.setAction(lAction);
591: }
592: }
593: }
594:
595: /** Returns page id obtained from the document */
596: private static String getPageId(Class pDocumentClass) {
597: java.util.zip.CRC32 lCRCUtil = new java.util.zip.CRC32();
598: lCRCUtil.update(pDocumentClass.getName().getBytes());
599: return Long.toString(lCRCUtil.getValue(), Character.MAX_RADIX);
600: }
601:
602: /** Returns page URL obtained from the document */
603: private static String getPageUrl(Class pDocumentClass) {
604: try {
605: Field lField = pDocumentClass.getField("XMLC_SOURCE_FILE");
606: String lUrl = (String) lField.get(null);
607: if (!lUrl.startsWith("/"))
608: return "/" + lUrl;
609: return lUrl;
610: } catch (NoSuchFieldException e) {
611: throw new IllegalArgumentException(
612: "Supplied class "
613: + pDocumentClass.getName()
614: + " does not appear to be valid XMLC generated document class. Caugt reflection exception : "
615: + e.toString());
616: } catch (IllegalAccessException e) {
617: throw new IllegalArgumentException(
618: "Supplied class "
619: + pDocumentClass.getName()
620: + " does not appear to be valid XMLC generated document class. Caugt reflection exception : "
621: + e.toString());
622: }
623: }
624: }
|